On Tue, 2004-01-06 at 22:26, Austin Hastings wrote:

> So on the grand balance of utility, what are the metrics that traits are
> supposed to help improve?

Two big ones:

        - naming collections of behavior that are too fine-grained to fit into
classes cleanly
        - enabling finer-grained code reuse

Consider a method that needs to print an object.  You might require a
String:

        sub print_it ( String $thingie )
        {
                print $thingie;
        }

Why does it have to be a String, though?  What prevents it from working
with anything that can stringify, besides the overly restrictive
signature?  What if you could say (the Perl 6 equivalent of): 

        sub print_it ( does Stringify $thingie )
        {
                print $thingie.stringify();
        }

That's both more general and something more specific.  By asking for
what you really want, you're not coding everyone else into a corner.

Take Mail::SimpleList and Mail::TempAddress, for example.  Both have
classes that represent individual addresses or mailing lists.  The
appropriate parent class is Mail::Action::Address, which has the very
basic data and properties that both subclasses share.

Both simple lists and temp addresses should contain expiration dates, so
both classes need some sort of behavior to implement that.

When you throw another class into the mix, say, Mail::OneWayList, where
there's no expiration (trust me, even though it's not on the CPAN yet),
there's a problem.

I'd like to share code between all three classes that represent aliases
and Mail::Action::Address is the appropriate place to do that.  I don't
want to share *all* of the code, though, so I can't really put the
expiration code in Mail::Action::Address.

I *could* subclass Mail::Action::Address and make
Mail::Action::Address::Expires and change the parent class of the temp
address and the simple list classes, but that's kinda icky as it leads
to yet another level in the class hierarchy.

By turning expiration into a role, though, everything can extend
Mail::Action::Address and only those classes that really need expiration
can do it -- and they share the code.

Contrived example?  Maybe.  Maybe not.  Consider further James
Fitzgibbon's Mail::Action::Role::Purge.  James wanted to extend all
Mail::Action subclasses to allow purging of expired addresses or lists. 
That's reasonable, but it's not something I wanted to add to
Mail::Action because it doesn't know anything about expiration.

So he made it a role and decorates expirable objects with the role and
can do what he wants there.

Again, the goals are specificity, genericity, and improved reuse.

-- c

Reply via email to