Skip to content

Roles, Singleton Methods & MooseX::Declare

June 10, 2009

If you feel that the “classic” Moose code in my last post seems a bit chunky when compared to the Ruby example then have a look at MooseX::Declare

MooseX::Declare cuts out the following boilerplate code from my previous Point example:

    {
        package Point;
        use Moose;
        ...
        no Moose;
        __PACKAGE__->meta->make_immutable;
    }

Down to just this:

use MooseX::Declare;
class Point {
    ...
}

Here is the first Point code & usage example using Moosex::Declare:

use MooseX::Declare;
 
class Point {    
    has x => ( isa => 'Int', is => 'rw' );
    has y => ( isa => 'Int', is => 'rw' );
 
    method negated   { $self->new( x => -$self->x, y => -$self->y ) }
 
    method transpose { $self->new( x => $self->y,  y => $self->x  ) }
 
    method inspect   { say $self->x . ' @ ' . $self->y              }
}
 
my $p = Point->new( x => 4, y => 3 );
 
$p->negated->inspect;      # => -4 @ -3
$p->transpose->inspect;    # => 3 @ 4
 
role Negated {
    requires 'transpose';
    method negated { $self->transpose };
}
 
Negated->meta->apply( $p );
$p->negated->inspect;      # => 3 @ 4
$p->transpose->inspect;    # => 3 @ 4

gist: 126839

Nice eh! Here is the second example of code transformed by MooseX::Declare:

use MooseX::Declare;

role DoesNegated {
    method negated { $self->new( x => -$self->x, y => -$self->y ) }
}

role DoesTranspose {
    method transpose { $self->new( x => $self->y, y => $self->x ) }
}

class Point with DoesNegated with DoesTranspose {    
    has x => ( isa => 'Int', is => 'rw' );
    has y => ( isa => 'Int', is => 'rw' );

    method inspect { say $self->x . ' @ ' . $self->y }
}

gist: 126849

Then like in previous post to apply a role to object is just:

DoesTranspose->meta->apply( $p, alias => { transpose => 'negated' } );

Now if that doesn't make you dribble then I don't know what will ;-)

/I3az/

About these ads
4 Comments leave one →
  1. geo permalink
    June 10, 2009 10:18 pm

    Really nice! I don’t know if it can get any better than this! Can it? :)

  2. June 11, 2009 2:16 am

    yeah, it will get even better :)

    The example doesn’t go into the powerful method signatures you get with MooseX::Declare and there’s already code out there for multi methods and return signatures. There’s planned enhances nearly CPAN ready for even more advanced type constraints and talk about Lisp style conditions.

    After that there’s going to be tons of new stuff in big projects like Catalyst and related, which has just recently become Moose based.

  3. June 11, 2009 7:50 am

    Like John has said this is only the beginning ;-)

    For eg. Here is a snippet from game.t test from MooseX::MultiMethods on GitHub @ http://github.com/rafl/moosex-multimethods/tree/master

    {
        package Paper;    use Moose;
        package Scissors; use Moose;
        package Rock;     use Moose;
        package Lizard;   use Moose;
        package Spock;    use Moose;
     
        package Game;
        use Moose;
        use MooseX::MultiMethods;
     
        multi method play (Paper    $x, Rock     $y) { 1 }
        multi method play (Paper    $x, Spock    $y) { 1 }
        multi method play (Scissors $x, Paper    $y) { 1 }
        multi method play (Scissors $x, Lizard   $y) { 1 }
        multi method play (Rock     $x, Scissors $y) { 1 }
        multi method play (Rock     $x, Lizard   $y) { 1 }
        multi method play (Lizard   $x, Paper    $y) { 1 }
        multi method play (Lizard   $x, Spock    $y) { 1 }
        multi method play (Spock    $x, Rock     $y) { 1 }
        multi method play (Spock    $x, Scissors $y) { 1 }
        multi method play (Any      $x, Any      $y) { 0 }
    }
    
    my $game = Game->new;
    ok($game->play(Spock->new, Scissors->new), 'Spock smashes Scissors');
    ok(!$game->play(Lizard->new, Rock->new), 'Rock crushes Lizard');
    ok(!$game->play(Spock->new, Paper->new), 'Paper disproves Spock');
    

    /I3az/

Trackbacks

  1. Moose fairy dust « transfixed but not dead!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: