Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I declare that a class uses more than one role with MooseX::Declare?

Tags:

perl

moose

Given that the roles Fooable and Barable have both been defined, how do I say that class FooBar does Fooable and Barable? I have no problem saying

#!/usr/bin/perl

use MooseX::Declare;

role Fooable {
    method foo { print "foo\n" }
}

role Barable {
    method bar { print "bar\n" }
}

class Foo with Fooable {}
class Bar with Barable {}

package main;

use strict;
use warnings;

Foo->new->foo;
Bar->new->bar;

But when I try to add

class FooBar with Fooable, Barable {}

I get the less than useful error

expected option name at [path to MooseX/Declare/Syntax/NamespaceHandling.pm] line 45

Just to prove to myself that I am not crazy, I rewrote it using Moose. This code works (but is uglier than sin):

#!/usr/bin/perl

package Fooable;
    use Moose::Role;    
    sub foo { print "foo\n" }

package Barable;    
    use Moose::Role;    
    sub bar { print "bar\n" }

package Foo;    
    use Moose;    
    with "Fooable";

package Bar;    
    use Moose;    
    with "Barable";

package FooBar;    
    use Moose;    
    with "Fooable", "Barable";

package main;

use strict;
use warnings;

Foo->new->foo;
Bar->new->bar;
FooBar->new->foo;
FooBar->new->bar;
like image 560
Chas. Owens Avatar asked Jul 19 '09 23:07

Chas. Owens


2 Answers

Apparently you need parentheses:

#!/usr/bin/perl

use MooseX::Declare;

role Fooable {
    method foo { print "foo\n" }
}

role Barable {
    method bar { print "bar\n" }
}

class Foo with Fooable {}
class Bar with Barable {}
class FooBar with (Fooable, Barable) {}

package main;

use strict;
use warnings;

Foo->new->foo;
Bar->new->bar;
FooBar->new->foo;
FooBar->new->bar;
like image 79
Chas. Owens Avatar answered Dec 27 '22 05:12

Chas. Owens


Just to note that this also works:

class FooBar with Fooable with Barable {}

This seems the most common usage I've seen in MooseX::Declare world.

Also note you can use the "classic" way also:

class FooBar {
    with qw(Fooable Barable);
}

There are cases where this is needed because this composes the role immediately whereas defining role in the class line gets delayed till the end of the class block.

like image 25
draegtun Avatar answered Dec 27 '22 04:12

draegtun