Jonathon Worthington just wrote about Perl 6's new support for parametric roles. Excellent!
Moose supports this feature too, through the MooseX-Role-Parameterized extension I wrote a little over a month ago. It has proved to be a very useful pattern. I'm pleased that Perl 6 has it built in.
Out of curiosity, I ported the examples Jonathon provided to MXRP. I'll have to work more with rafl to make MooseX-Declare support something resembling Perl 6's much nicer syntax. We do plan on having syntax for positional parameters in much the same way Perl 6's parametric roles do.
package Greet; use MooseX::Role::Parameterized; parameter greeting => ( is => 'ro', isa => 'Str', required => 1, ); role { my $p = shift; my $greeting = $p->greeting; method greet => sub { print "$greeting!\n"; }; }; package EnglishMan; use Moose; with Greet => { greeting => "Hello" }; package Slovak; use Moose; with Greet => { greeting => "Ahoj" }; package Lolcat; use Moose; with Greet => { greeting => "OH HAI" }; EnglishMan->new->greet; # Hello! Slovak->new->greet; # Ahoj! Lolcat->new->greet; # OH HAI!
I'll skip the second example because it's contained by the third example.
Moose doesn't give you multiple dispatch. sigh! Instead we model the problem with a default value for the transform, which is a code reference. In this way we meet the original requirement of EnglishMan and Lolcat not needing to provide a nominative->accusative transform.
package Request; use MooseX::Role::Parameterized; parameter statement => ( is => 'ro', isa => 'Str', required => 1, ); parameter transform => ( is => 'ro', isa => 'CodeRef', default => sub { sub { $_[0] }, # identity function }, ); role { my $p = shift; my $statement = $p->statement; my $transform = $p->transform; method request => sub { my ($self, $object) = @_; print "$statement " . $transform->($object) . "?\n"; }; }; package Language::Slovak; sub accusative { my $nom = shift; (my $acc = $nom) =~ s/a$/u/; return $acc; } package EnglishMan; use Moose; with Request => { statement => "Please can I have a" }; package Slovak; use Moose; with Request => { statement => "Prosim si", transform => \&Language::Slovak::accusative, }; package Lolcat; use Moose; with Request => { statement => "I CAN HAZ" }; EnglishMan->new->request("yorkshire pudding"); Slovak->new->request("boravicka"); Lolcat->new->request("CHEEZEBURGER");
I have no conclusion, except that Perl 5 hasn't been stagnant, though its new features can be a lot more verbose than in Perl 6.
Very nice, thanks for putting together that example.
- Stevan