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

Reply via email to