*{ $pkg . '::' . $name } = $code;
}
+# copied from Class::Inspector
+sub get_method_list {
+ my $self = shift;
+ my $name = $self->name;
+
+ no strict 'refs';
+ # Get all the CODE symbol table entries
+ my @functions = grep !/^meta$/,
+ grep { /\A[^\W\d]\w*\z/o }
+ grep { defined &{"${name}::$_"} }
+ keys %{"${name}::"};
+ wantarray ? @functions : \@functions;
+}
+
sub add_attribute {
my $self = shift;
my $attr = shift;
sub get_attribute_list { keys %{ $_[0]->{attributes} } }
sub get_attribute { $_[0]->{attributes}->{$_[1]} }
+# copied from Class::Inspector
+sub get_method_list {
+ my $self = shift;
+ my $name = $self->name;
+
+ no strict 'refs';
+ # Get all the CODE symbol table entries
+ my @functions = grep !/^meta$/,
+ grep { /\A[^\W\d]\w*\z/o }
+ grep { defined &{"${name}::$_"} }
+ keys %{"${name}::"};
+ wantarray ? @functions : \@functions;
+}
+
sub apply {
my $self = shift;
+ my $selfname = $self->name;
my $class = shift;
+ my $classname = $class->name;
for my $name (@{$self->{required_methods}}) {
- unless ($class->name->can($name)) {
- confess "'@{[ $self->name ]}' requires the method '$name' to be implemented by '@{[ $class->name ]}'";
+ unless ($classname->can($name)) {
+ confess "'$selfname' requires the method '$name' to be implemented by '$classname'";
+ }
+ }
+
+ {
+ no strict 'refs';
+ for my $name ($self->get_method_list) {
+ next if $name eq 'has' || $name eq 'requires' || $name eq 'meta' || $name eq 'with' || $name eq 'around' || $name eq 'before' || $name eq 'after' || $name eq 'blessed' || $name eq 'extends' || $name eq 'confess' || $name eq 'excludes';
+ if ($classname->can($name)) {
+ # XXX what's Moose's behavior?
+ next;
+ }
+ *{"${classname}::${name}"} = *{"${selfname}::${name}"};
}
}
}
}
+sub apply_all_roles {
+ my $meta = Mouse::Meta::Class->initialize(shift);
+ my $role = shift;
+ confess "Mouse::Util only supports 'apply_all_roles' on individual roles at a time" if @_;
+
+ Mouse::load_class($role);
+ $role->meta->apply($meta);
+}
+
1;
__END__
--- /dev/null
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More tests => 4;
+use Mouse::Util ':test';
+
+{
+ package FooRole;
+ use Mouse::Role;
+ sub foo { 'ok1' }
+}
+
+{
+ package BarRole;
+ use Mouse::Role;
+ sub bar { 'ok2' }
+}
+
+{
+ package Baz;
+ use Mouse;
+ no Mouse;
+}
+
+throws_ok { Mouse::Util::apply_all_roles('Baz', 'BarRole', 'FooRole') } qr{Mouse::Util only supports 'apply_all_roles' on individual roles at a time};
+
+Mouse::Util::apply_all_roles('Baz', 'BarRole');
+Mouse::Util::apply_all_roles('Baz', 'FooRole');
+
+my $baz = Baz->new;
+is $baz->foo, 'ok1';
+is $baz->bar, 'ok2';
+is join(",", sort $baz->meta->get_method_list), 'bar,foo';
+