Re: RFC: Automatic accessors for hash-based objects

[email protected] (Nathan Wiger)
Newsgroups perl.perl6.language.objects
Message-ID <[email protected]>
First off, I like the idea a lot. However, I think there is some
extraneous bloat in it:

> The defined permissions are:
> 
>     '!', which forces the method call to fail, without further ado L<[5]>, and
>     '+', which makes the autoaccessor handle the call
>     '~', which makes the autoaccessor fail, but allow traditional ways
>          of handling the method call..
> 
> The default is '+', if no permission is specified for a context.

I completely miss the point of these. Isn't '!' the same as not
specifying ':accessible', since the autoaccessor method therefore won't
exist and either the defined class one or AUTOLOAD will still be called?
And isn't '+' the same as specifying ':accessible'? And how could you
ever use '~'? 

If I have a piece of code (I'll use :access because it's a lot shorter):

   # ...
      $self->{name} : access = "Nate"; 
   # ...
 
   sub name {
       # ...
   }

Then just specifying ':access' should cause it to override name(), which
is in Perl already ("subroutine name() redefined..."). If I then drop
the ':access', name() will be called. And if name() didn't exist, then
AUTOLOAD would be called. The !,+,~ permissions uselessly duplicate
this, as far as I can tell.

> A context with a '~' permission is the same as not specifying the
> context letter at all L<[7]>, and is included only for completeness.
> 
> The context can be:
> 
>     'r' for rvalue (or 'r' for read)
>     'l' for lvalue (or 'w' for write)
>     'm' for mutator (which has no synonym) L<[6]>

I don't see why you'd want to restrict l/r sides if they're hash keys.
This is implicit in making them readonly. If the user tries to use a
readonly variable in an lvalue assignment, then it's an error. And
telling them they can't use a writeable value on the l side makes that
readonly implicitly. 

So I would drop this, it's unnecessary and complex. All of it is taken
care of by a :constant keyword. Just include a :constant attribute for
those things you want readonly:

     $self->{DEFAULT_DIR} : access, constant = '/usr/bin';
     $self->{name} : access = "Nate";
     $self->{peers} : access = undef;

That is a lot simpler and seems to feel a lot better. Note again I
chopped it to 'access' to save typing. It also seems to accomplish the
same thing, unless I'm missing something huge.

I think the idea's great, but I think the only thing it needs to do is
introduce a new ':access' attribute which basically just makes it
possible to drop {}'s in access calls. The other stuff can be handled by
combinations with other RFC's and existing Perl stuff.

Finally, one thing that you should address is how to handle multi-level
hashes:

     $self->{CONFIG}->{DEFAULT_DIR} : access, constant = '/usr/bin';
     $self->{STATE}->{name} : access = "Nate";
     $self->{STATE}->{peers} : access = undef;

Which is how I store data internally in my modules. Seems to me that you
could make Perl Do The Right Thing by implicitly remembering the proper
hash level:

     $self->DEFAULT_DIR   # $self->{CONFIG}->{DEFAULT_DIR}
     $self->peers         # $self->{STATE}->{peers}
     $self->name          # $self->{STATE}->{name}

Then, if someone defined the same end node in multiple levels and tried
to use ':access' on both of them, simply issue a "subroutine
DEFAULT_DIR() redefined at line..." warning.

     $self->{CONFIG}->{DEFAULT_DIR} : access, constant = '/usr/bin';
     $self->{STATE}->{DEFAULT_DIR} : access;  # "sub redefined" warning

-Nate
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.