On Fri, Apr 23, 2004 at 03:34:32PM -0700, Jonathan Lang wrote: : Larry Wall wrote: : > On Fri, Apr 23, 2004 at 02:37:58PM -0700, Jonathan Lang wrote: : > : Note that the problem extends past accessors: a role's methods can : > : access its attributes directly. So: : > : : > : role A {has Cat $.x; method m1 {return $.x;};} : > : role B {has Dog $.x; method m2 {return $.x;};} : > : class Foo {does Cat; does Dog;} : > : my Foo $bar; : > : $bar.m1; # returns $A::x, right? : > : $bar.m2; # returns $B::x, right? : > : : > : If the two $.x's are completely equivelent, you end up with redundant : > : data storage. : > : > Actually, it'd blow up at composition time anyway, since there's a : > default readonly accessor for each $.x variable. : : OK; so add "method x {...};" to class Foo to keep it from blowing up. Foo : still has to track two scalars internally. : : Actually, it's worse than that: let's add "has Elephant $.x;" to Foo : instead. Since class trumps role, does $bar.m1 now work with an Elephant, : or does it still work with a Cat?
I think the attributes have to be considered to belong primarily to the role, and a role that references one of its own attributes knows that it is doing so to the exclusion of any other similarly named attribute in the class or in a different role. Accessing a role's attribute from within a class or another role should really only work as a fallback, if at all. I think people should be encouraged to use the methods where performance is not at a premium. Most of these will be private attributes in any event, so using the :method doesn't have to do virtual dispatch. But private attributes also belong primarily to the role, and only secondarily to the class or other roles. However, the roles do implicitly trust each other by virtue of being composed into the same class, so they can see each other's private methods. Note that this means you can write roles that are only meaningful when composed into a class with certain other roles or methods, and cannot be used as mixins, since a mixin would never see the private methods from an overridden base class. The only way to do it as a mixin is to have a composite role containing all the other roles, and then mix that one role in all at once. (Which is probably what you want to do anyway for efficiency, when you know you have to mix in multiple roles.) Larry