From: chromatic [mailto:[EMAIL PROTECTED] > 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.
This seems to have some pretty strong AOP implications. I can easily see wanting to generically extend all classes with a capability (role). So, first, can I define "inferred" roles? For example: role Printable { requires toString(); } such that any object which has a toString method is considered to C<does Printable>? If so, can I use junctions to do so? (requires toString()|toInt()|toDouble()) Next, is there a good way to aspectify this, so that I can impose it without having to write code to manipulate the namespace and extend every class? class [* isa Object] but= Printable; # All children of Object are printable > 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. Cool, thanks. =Austin