}
}
- for my $name ($self->get_attribute_list) {
- next if $class->has_attribute($name);
- my $spec = $self->get_attribute($name);
- Mouse::Meta::Attribute->create($class, $name, %$spec);
+ if ($class->isa('Mouse::Meta::Class')) {
+ # apply role to class
+ for my $name ($self->get_attribute_list) {
+ next if $class->has_attribute($name);
+ my $spec = $self->get_attribute($name);
+ Mouse::Meta::Attribute->create($class, $name, %$spec);
+ }
+ } else {
+ # apply role to role
+ # XXX Room for speed improvement
+ for my $name ($self->get_attribute_list) {
+ next if $class->has_attribute($name);
+ my $spec = $self->get_attribute($name);
+ $class->add_attribute($name, $spec);
+ }
}
+ # XXX Room for speed improvement in role to role
for my $modifier_type (qw/before after around/) {
my $add_method = "add_${modifier_type}_method_modifier";
my $modified = $self->{"${modifier_type}_method_modifiers"};
sub extends { confess "Roles do not support 'extends'" }
-sub with { confess "Mouse::Role does not currently support 'with'" }
+sub with {
+ my $meta = Mouse::Meta::Role->initialize(caller);
+ my $role = shift;
+ confess "Mouse::Role only supports 'with' on individual roles at a time" if @_;
+
+ Mouse::load_class($role);
+ $role->meta->apply($meta);
+}
sub requires {
my $meta = Mouse::Meta::Role->initialize(caller);
--- /dev/null
+use strict;
+use warnings;
+use Test::More tests => 4;
+
+{
+ package Animal;
+ use Mouse::Role;
+ sub eat { 'delicious' }
+ has food => ( is => 'ro' );
+}
+
+{
+ package Dog;
+ use Mouse::Role;
+ with 'Animal';
+}
+
+{
+ package Chihuahua;
+ use Mouse;
+ with 'Dog';
+}
+
+ok !Animal->can('food');
+ok !Dog->can('food');
+
+my $c = Chihuahua->new(food => 'bone');
+is $c->eat(), 'delicious';
+is $c->food(), 'bone';
+