----- Original Message ---- > From: Jonathan Worthington <jonat...@jnthn.net>
> Ovid wrote: > > It needs the timed fuse() from a Bomb role and a non-lethal explode() from > > a > Spouse role, though each role provides both methods. > I'm curious... > > 1) How often do you in real life find yourself needing to do things like this > in > real life? This is a sort of strained, if amusing, example. :-) We use roles very, very heavily. We've found that the important thing is choosing descriptive names. Thus, we rarely need to exclude methods from roles because our names are unambiguous. The only time I recall us running into this problem is when we have two or more methods with identical names which perform semantically identical behaviors but need different implementations. > 2) A lot of me wonders if a need to exclude a method from a role is a hint > that > the role does too many things and should be decomposed into smaller pieces, > such > that it can be applied in a more "granular" way? As noted, we only have this happen when the semantics are identical but the implementation must differ. At this point, we really do need a way to exclude methods. This doesn't happen very often, but it's happened enough (probably about 10 times in our code base) that a convenient way of handling this would be useful. > I'm curious to hear the experiences of Ovid and others working with roles a > lot > too. Is this a serious lacking in Perl 6's roles as currently specified, or > something that, in being absent, makes people consider their design more? > Knowing that will influence the solution we choose, which has options ranging > from, "yes, make a neat syntax for it" through "leave it out of the core, and > if > people want it enough it can be a CPAN module". Actually, the only serious concern I have (pardon me if you've heard this before) is how we silently discard a role's method if the class provides it. A digression is in order. Some of you know the background behind roles, but not everyone. The problem with classes is that they tend to have two competing uses. Classes are agents of responsibility (which tends to make them grow larger) and, via inheritance, are agents of code reuse (which tends to want classes to be smaller). These competing tendencies have been a source of much OO pain and roles decouple the behavioral reuse from class responsibility quite nicely. That being said, roles also have two competing uses (though they don't conflict as badly). As units of behavior, they provide the functionality your code needs. However, they can also serve as an interface. The behavioral/interface divide has already demonstrated a subtle tension in the use of roles in my work. For those of you who have seen the arguments about this rage on use.perl, my apologies :( Interface: if you are taking advantage of a role as an interface, it's quite useful to have your class provide one or more methods with an identical signature to the role and have the role's method silently ignored. Behavioral: if you are primarily relying on roles to provide behavior (as we do at the BBC), then silently discarding the role's behavior by providing a method of the same name in your class can lead to very confusing bugs. I've lost a lot of time debugging this behavior. I'd like to see something like this (or whatever the equivalent Perl 6 syntax would be): class PracticalJoke does Bomb does SomeThingElse { method fuse() but overrides { ... } } The "overrides" tells Perl 6 that we're overriding the fuse() method from either Bomb or SomeThingElse (or both). Otherwise, a warning or exception would be useful to prevent me from accidentally overriding needed behavior. Again, we've lost a huge amount of time debugging this behavior with Moose::Roles and I'd hate to have to do this again with Perl 6. Your mileage may vary :) Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Tech blog - http://use.perl.org/~Ovid/journal/ Twitter - http://twitter.com/OvidPerl Official Perl 6 Wiki - http://www.perlfoundation.org/perl6