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