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]