tags:

views:

122

answers:

2

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;
+5  A: 

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;
Chas. Owens
Yes, the documentation says `with (@roles)`. My only question would have been about the barewords in a list.
David Toso
What docs are you using? The MooseX::Declare docs say `class Foo with Role { ... }`. The Moose docs say `with (@roles)`, but then all of the examples are like `with 'Breakable';`
Chas. Owens
+4  A: 

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.

/I3az/

draegtun