On Tue, Nov 01, 2005 at 04:02:04PM -0800, Jonathan Lang wrote: > True enough; but it needn't be true that d have the same tools > available to resolve the conflicts that c has. > > There are three ways that a role can deal with a conflict: > > 1. choose one of a set of available methods to call its own. > 2. create a version of its own. > 3. pass the buck. > > In the first case, the question is how we define the set of available > methods: do we make the full hierarchy of ancestors available to the > role, or do we say that only the immediate parents are available?
People keep using the word "hierarchy" when talking about roles and I keep thinking that it is the one word that definitely does NOT apply. Heirarchies are for classes and inheritance relationships, not roles and composition. In my world view, a role that is composed of two other roles has full view of the methods/attributes defined in the roles that compose it because the landscape is quite flat. There are no hills and valleys. When it finally comes down to composing into a class, the class sees all of the methods/attributes provided by each and every role even the role inside a role inside a roles. > Another way to put this would be: should the "DOESA" list be treated > as public or private? (My preference: the "DOESA" list should be > private. You don't lose any capabilities by doing so, other than the > capability to access stuff not explicitly declared - a capability that > roles don't need, and probably shouldn't have.) If "DOESA" is > private, then d won't have access to anything from a or b without > explicitly including them in its own DOESA list. This seems to be > restrictive, and it is - but only in the same way that making an > attribute private is restrictive. When you say: role A { ... } role B { ... } role C does A does B { ... } role D does C { ... } roles A and B are composed into C at compile time. If both A and B define a method foo(), then there is a conflict (immediately, at compile time) unless you've somehow told perl that it should defer composition until it's actually composing classes. What's really at question I think is whether the _default_ is to compose immediately or to postpone composition until there's a class to compose into. If you have roles that are never composed into classes, then it won't matter if there's a conflict as you can't instantiate a role (not without first turning it into a class). So, on one hand it does make sense to defer composition until there's a class to compose into. But it also makes sense to deal with composition conflicts incrementally too (as roles are composed into other roles). > The second case is pretty straightforward. And isomorphic to the first case as it is the resolution to the first case. > In the third case, I'd be inclined to say that passing the buck is > equivalent to creating an undefined version of your own - that is, not > addressing a conflict involving method x is equivalent to saying > "method x ($arg) { ... }". IOW, a class that does a role that passed > the buck is faced with an "undefined method" complaint if it doesn't > do something about it, not an "unresolved conflict" complaint. Nah, the third case is ye olde standard conflict, just perhaps occurring at a different space+time than had the roles been composed immediately. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]