develooper Front page | perl.perl6.language | Postings from May 2004

Re: How do I do parametered roles?

Thread Previous | Thread Next
From:
Luke Palmer
Date:
May 1, 2004 00:31
Subject:
Re: How do I do parametered roles?
Message ID:
20040501073146.GA8418%luke@luqui.org
Austin Hastings writes:
> > So what you want is a role whose names are private to the role, not the
> > aggreagating class.  Well, I believe private (i.e. $:foo) variables do
> > that anyway, so you can just abstract your messages out into a role and
> > it will work fine.  But if you read on, I'll offer some unsolicited
> > design advice.
> 
> Hmm. No. I want a role whose methods are available in the composing
> class, as shown. Variables (members) don't have roles: Roles (may)
> have variables.

Right, and those variables in turn become part of the *composing class.
Unless they're private.

> Saying "class Session does MessageList" means that MessageList may
> impose member variables on Session, and will provide methods to
> Session. Roles are composition, not aggregation.

Whoops, got my vocabulary backwards.  Trust me, we're on the same page
here.

> > > One solution is to compose member objects that implement this behavior:
> > > 
> > >   if ($my_object.messages.have_messages) {...}
> > > 
> > > But that sucks.
> > 
> > Why?  From a design perspective, that's the correct way to do it.  What
> > if you have a routine that operates on message lists -- pruning them or
> > somesuch.  If you do it by renaming the methods, you break any kind of
> > future-proof code reuse that abstracting gets you in the first place.
> 
> You've got it backwards: saying $my_object.messages.have_messages is
> exposing the fact that the have_messages functionality is implemented
> via a member data item, instead of querying the $my_object directly.

This was in my "unsolicited design advice" section, where I was
proclaiming that it should be.

> > But this isn't an OO design list, it's a language design list.
> 
> And "how to make the names more readable" isn't "how to parameterize
> member/method names".

Okay, so you want to use a role to integrate a behavior, but with PHPly
slightly different method names.  You've given your brain time, and
after a few beers, it still decides it wants to do this.  Well, you'll
be spending a lot of time hacking around, while someone else with an
equally insane idea has come up with a simple solution without using
roles:

    class MessageList {
        method have_messages() {...}
        method get_messages() {...}
        method add_message($msg) {...}
        method clear_messages() {...}
    }

    class Session {
        has $:messages handles /_messages?$/;
        has $:errors handles (s/_error(s?)$/_message$1/);
    }

> > 
> > If it turns out that role private variables leak, I might suggest making
> > a MessageList class as above, then making a role that knows how to turn
> > a MessageList into a set of methods.  Then you'd pass the role the
> > MessageList object which you instantiate yourself, and it would generate
> > the methods for you.  That's kind of a kludge, but you're using roles
> > for something they're not really intended for, so that's what you get.
> > Keep in mind that there are plenty of other ways to do what you want;
> > this is Perl, after all.
> 
> Hmm. Why is this not what roles are intended for? I have identified a
> packageable, reusable behavior that I want to insert into a class
> using some mechanism other than inheritance. I could have sworn that
> was the whole point of roles.
> 
> In this particular case, however, I've gone one step beyond and
> identified a "generic" behavior, that I'd like to implement multiple
> times with slightly different names.

And it's that last part that roles weren't intended for.  A role is like
a Java interface[1] in that it provides a set of names that other users
can count on being there.  If you ask for PHPly, slightly modified names
then there's no set of names that the role provides.  Now it's just
providing implementations, and you're providing the names.  That sounds
much more like delegation to me.  Or insanity.

Luke

[1] Except, because it can provide as well as require methods, it turns
out to be useful.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About