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

Reply via email to