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