Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

sartak (7900)

sartak
  (email not shown publicly)
http://sartak.katron.org/

Journal of sartak (7900)

Saturday January 17, 2009
03:21 PM

MooseX::Role::Parameterized

[ #38309 ]

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("CHEEZEBURG ER");

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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.