Ovid wrote:
Giving a talk about roles at YAPC::EU in Lisbon
Hey, me too! :-)

and I'm a bit stuck on how to translate a Perl 5 example into Perl 6.  Basically, Imagine 
a "PracticalJoke" class which has fuse() and explode methods().  It needs the 
timed fuse() from a Bomb role and a non-lethal explode() from a Spouse role, though each 
role provides both methods.  In Moose, it's easy:

  package PracticalJoke;
  use Moose;
  with 'Bomb'   => { excludes => 'explode' };
       'Spouse' => { excludes => 'fuse' };

Try as I might, I can't figure out how to translate that into Perl 6.  I have 
the following:

  role Bomb {
    method fuse ()    { say '3 .. 2 .. 1 ..' }
    method explode () { say 'Rock falls. Everybody dies!' }

  role Spouse {
    method fuse ()    { sleep rand(20); say "Now!" }
    method explode () { say 'You worthless piece of junk! Why I should ...' }

  class PracticalJoke does Bomb does Spouse {

Nothing I see in S14 (http://perlcabal.org/syn/S14.html) seems to cover this case. I 
can't declare them as multis as they have the same signature.  There's a note that one 
can "simply to write a class method that overrides the conflicting role methods, 
perhaps figuring out which role method to call", but I don't understand how a 
particular role's methods would be called here.

The spec is right in that you need to write a method in the class that decides what to do. This will look something like:

   method fuse() { self.Bomb::fuse() }

Or also if you like you can probably get away with:

   method fuse() { $.Bomb::fuse() }

But be aware that then you're forcing item context on the return value.

Note that this is NYI in Rakudo, but I hope to do it fairly soon (before YAPC::EU).



Reply via email to