----- Original Message ----- From: "Luke Palmer" <[EMAIL PROTECTED]> To: "Joe Gottman" <[EMAIL PROTECTED]> Cc: "Perl6" <[EMAIL PROTECTED]> Sent: Tuesday, January 06, 2004 9:34 PM Subject: [perl] Re: Roles and Mix-ins?
> Joe Gottman writes: > > > > ----- Original Message ----- > > From: "Luke Palmer" <[EMAIL PROTECTED]> > > To: <[EMAIL PROTECTED]> > > Sent: Tuesday, January 06, 2004 4:51 AM > > Subject: [perl] Re: Roles and Mix-ins? > > > > > > > David Storrs writes: > > > > > > > > On Sat, Dec 13, 2003 at 11:12:31AM -0800, Larry Wall wrote: > > > > > On Sat, Dec 13, 2003 at 04:57:17AM -0700, Luke Palmer wrote: > > > > > > > > > : For one, one role's methods don't silently override another's. > > Instead, > > > > > : you get, er, role conflict and you have to disambiguate yourself. > > > > > > > > How do you disambiguate? > > > > > > Let's see... > > > > > > role Dog { > > > method bark() { print "Ruff!" } > > > } > > > role Tree { > > > method bark() { print "Rough!" } > > > } > > > class Trog > > > does Dog does Tree { > > > method bark() { .Dog::bark() } > > > } > > > } > > > > > > Perhaps something like that. In any case, you do it by putting the > > > offending method directly in the aggregating class. > > > > > > > How about something like > > class Trog > > does Dog {bark=>dogBark} does Tree {bark=>treeBark} > > {...} > > > > Then we could have code like > > my Trog $foo = Trog.new(); > > my Dog $spot := $foo; > > my Tree $willow := $foo; > > $spot.bark(); # calls dogBark() > > $willow.bark(); #calls treeBark() > > > > This works better when Dog::bark and Tree::bark are both needed but they > > do different things. > > Renaming methods defeats the purpose of roles. Roles are like > interfaces inside-out. They guarantee a set of methods -- an interface > -- except they provide the implementation to (in terms of other, > required methods). Renaming the method destroys the interface > compatibility. > > Your renaming can be done easily enough, and more clearly (IMO) with: > > class Trog > does Dog does Tree { > method bark() { ... } # Explicitly remove the provided method > method dogBark() { .Dog::bark() } > method treeBark() { .Tree::bark() } > } But won't explicitly removing bark() from the class also disable Dog::bark() and Tree::bark() for the class? Renaming would work if other methods in Dog are directed to dogBark() when they call bark(), and other methods in Tree are redirected to treeBark(). Joe Gottman