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