Subject: | Roles which require methods cannot be composed |
Given a role like:
{
package MyRole;
use Moose::Role;
has monkeys => (is => 'rw');
requires 'bananas';
}
It will throw when you try to compose it with MXCC unless you also
compose a role that implements bananas.
The attached patch (and test case) provides a simple solution for this
problem.
Subject: | mxcc.t |
{
package MyRole;
use Moose::Role;
has monkeys => (is => 'rw');
requires 'bananas';
}
use MooseX::ClassCompositor;
use Test::More tests => 3;
my $comp = MooseX::ClassCompositor->new(
class_basename => 'MyClass',
);
my $class = $comp->class_for(
{ bananas => sub { 'yellow ones' } },
'MyRole',
);
my $inst = $class->new(monkeys => 1);
ok($inst->DOES('MyRole'), "$class\->does('MyRole')");
can_ok($inst => 'bananas');
can_ok($inst => 'monkeys');
Subject: | mxcc.diff |
--- /usr/lib/perl5/site_perl/5.10.1/MooseX/ClassCompositor.pm 2012-02-14 21:46:00.000000000 +0000
+++ MooseX/ClassCompositor.pm 2012-03-30 21:31:20.806043797 +0100
@@ -98,11 +98,14 @@
# $role_hash is a hash mapping nonce-names to role objects
# $role_names is an array of names of more roles to add
- my (@roles, @role_class_names, @all_names);
+ my (@roles, @role_class_names, @all_names, %subs);
while (@args) {
my $name = shift @args;
- if (ref $name) {
+ if (ref $name eq 'HASH') {
+ $subs{$_} = $name->{$_} for keys %$name;
+ next;
+ } elsif (ref $name eq 'ARRAY') {
my ($role_name, $moniker, $params) = @$name;
my $full_name = $self->_rewrite_roles($role_name);
@@ -140,6 +143,7 @@
my $class = Moose::Meta::Class->create( $name => (
superclasses => [ 'Moose::Object' ],
+ methods => { %subs },
));
$class = Moose::Util::MetaRole::apply_metaroles(
@@ -164,7 +168,11 @@
my @k;
while (@args) {
my $arg = shift @args;
- if (ref $arg) {
+ if (ref $arg eq 'HASH') {
+ push @k,
+ map { sprintf('FUNC(%s): { %s }', $_, refaddr($arg->{$_})) }
+ sort keys %$arg;
+ } elsif (ref $arg eq 'ARRAY') {
my ($role_name, $moniker, $params) = @$arg;
push @k, "$moniker : { " . __hash_to_string($params) . " }";
} else {
@@ -298,6 +306,14 @@
Note that at present, passing Moose::Meta::Role objects is B<not> supported.
This should change in the future.
+Additional methods that the class should provide may be passed as a hashref.
+This allows any methods required by the role to be implemented.
+
+ my $class = $compositor->class_for(
+ 'Role::Name',
+ { my_method => sub { ... } },
+ );
+
=head1 THANKS
Thanks to Pobox.com for sponsoring the development of this library.