Ovid wrote:
I was asking the special case where:
1. A class consumes two (or more) roles
2. Each roles provides a method with an identical signature
3. The methods are not equivalent and neither role can rely on the other's
method
With that, you have roles which cannot be composed. You must rewrite one (bad if you don't own it), or omit one..
When a role is composed into a class, it does quite literally become as
if it were declared within the class itself (appears directly in the
methods list), but equally does not lose its lexical scoping
relationship with the role it was declared in either. Would it help to
say that when a method declared within a role invokes another method,
then we first search the methods within that role's lexical scope?
Therefore:
role Drinking {
method buy_beer() {
self.go_to_bar();
...
}
method go_to_bar() {
...
}
}
role Gymnastics {
method go_to_bar() {
}
}
class DrunkGymnast does Drinking does Gymnastics {
method go_to_bar() {
# something to resolve the conflict here
}
}
This way, the method "buy_beer" will always consider methods in its
lexical scope first and thus find the role's "go_to_bar" rather than the
one in the class. Of course, if the role's lexical scope had no methods
of that name declared within it we'd go elsewhere.
That said, lexical scope maybe is the wrong thing too, and we really
just care about the role's method table. Some mechanism that gives
"method in a role doing an invocation looks first at other methods in
the same role" may help though.
Of course, then people will probably complain they can no longer provide
a default and have the class override it when they want to, though I
rather suspect that:
self.$?CLASS::method_name(...)
May just be something we can bend into solving that problem without too
much effort.
Thanks,
Jonathan