On Thu, Jul 21, 2005 at 05:15:34PM -0400, Stevan Little wrote:
: Larry,
: 
: This means that Roles are now first-class-ish things. Meaning they 
: cannot just simply be composed into classes since now we have to keep a 
: table of elements which are private to a Role.

Well, we've kinda been squinting at that issue from both ends for a
while now, and there's something in both views.

: I personally don't like this, I think it brings us back to Mix-ins and 
: (possibly) looses some of the benefits of Roles. But that is just my 
: initial gut reaction. I am going to have to let is sink in a little 
: more to know for sure. In the meantime I have some questions:
: 
: On Jul 21, 2005, at 2:48 PM, Larry Wall wrote:
: >    * All roles can write their shared attributes as $.x and not worry
: >     about whether the class declares them or not.
: 
: I assume they need not worry because we can rely on conflict resolution 
: to deal with most issues? Or are you thinking something different?

No, that's correct.  We've just basically said that $.x is now a method
call, and as long as you stick to that invocation syntax it just has
to be declared as a method somewhere in the parentage/role-age of
this object.  But collisions in $.x declaration will be treated as
collisions in method declaration.

: >    * All roles can write completely private $x attributes that are not
: >     visible outside their lexical scope but are nevertheless 
: >     per-instance.
: 
: So the Role's scope is preserved here, as opposed to pushing $x into 
: the classes scope. Correct?

My notion is that $x (the name proxy) is stored in the lexical scope
of the closure that just happens to be the closure for the role,
rather than keeping a name proxy in the package.  In either case,
$x or $.x is not a real variable, but a placeholder for a particular
slot in the object.  The actual proxy could be stored in the role's
package if that makes it easier to keep track of, but I'd like the
scoping of the name to be lexical like an "our" in that case.  But if
we can figure out how to store it more like a "my" variable but still
figure out which slot it maps to when instantiated, that might be cool.
Unfortunately, it could map to different slots in different objects,
so the class in question would have to keep track of where MyRole::('$x')
actually maps to.

It's certainly possible that this notion doesn't really map terribly
well onto roles.  I was just hoping for a way to encourage people
to write private attributes, and shortening $.x to $x for that seemed
like good huffmanization in the class, as long as $x actually scopes
to being very private and doesn't interfere in any way with the
class's public interface.  So basically if the role can carry the
same idea through and allow "local" attributes that have guaranteed
zero influence on the interface, that'd be cool too.

: >    * All roles can write explicitly shared $_x attributes that are 
: >private
: >     to the class but visible to other roles and trusted classes.
: 
: What other roles? the other roles that the class does()?

That's what I meant.  $_x variables are the old $:x, basically, and
while they have some kind of proxy in the class's package space, the
leading character is examined to enforce namespace distinction and
some amount of privacy.  Like the old $:x they also imply private
accessors that are really little more than subs you can call with
method syntax.

: This would 
: make it difficult to compose role methods into the method table without 
: bringing along a lot of meta-info about from whence they came. It is 
: doable I think, but adds some complexity for which I am not sure the 
: cost outweighs the benefits.

It's possible that roles should only do the class-based $_x and $.x,
and leave the lexically named $x to the class, unless we can figure
out how the class can keep track of the role's lexical scope and/or
package.

But I like the $x/$.x distinction for classes, since it encourages
people to write completely private attributes to begin with, and
then maybe take the step of adding a dot when the want to provide
an accessor.

One other implementation downside I didn't mention is that it makes
it a little harder to decide that

    submethod BUILD ($x) {...}

wants to set the private $x attribute.  Though in theory we can see the $x
declaration from the BUILD declaration.  However, we still get

    submethod BUILD ($_x) {...}

pretty much for free.

Larry

Reply via email to