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/

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 comment