----- 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



Reply via email to