role application works for a simple case
Matt S Trout [Mon, 2 Apr 2012 18:38:23 +0000 (18:38 +0000)]
lib/Moo/HandleMoose.pm
lib/Moo/Role.pm
xt/handle_moose.t

index ce9a1c6..08f49a6 100644 (file)
@@ -8,6 +8,7 @@ sub import { inject_all() }
 sub inject_all {
   require Class::MOP;
   inject_fake_metaclass_for($_) for grep $_ ne 'Moo::Object', keys %Moo::MAKERS;
+  inject_fake_metaclass_for($_) for keys %Moo::Role::INFO;
 }
 
 sub inject_fake_metaclass_for {
@@ -25,12 +26,12 @@ sub inject_real_metaclass_for {
   return Class::MOP::get_metaclass_by_name($name) if $DID_INJECT{$name};
   require Moose; require Moo; require Moo::Role;
   Class::MOP::remove_metaclass_by_name($name);
-  my ($meta, $attr_specs) = do {
+  my ($am_role, $meta, $attr_specs) = do {
     if (my $info = $Moo::Role::INFO{$name}) {
-      (Moose::Meta::Role->initialize($name), $info->{attributes})
+      (1, Moose::Meta::Role->initialize($name), $info->{attributes})
     } else {
       my $specs = Moo->_constructor_maker_for($name)->all_attribute_specs;
-      (Moose::Meta::Class->initialize($name), $specs);
+      (0, Moose::Meta::Class->initialize($name), $specs);
     }
   };
   my %methods = %{Role::Tiny->_concrete_methods_of($name)};
@@ -41,9 +42,11 @@ sub inject_real_metaclass_for {
       push @attrs, $meta->add_attribute($name => %{$attr_specs->{$name}});
     }
   }
-  foreach my $attr (@attrs) {
-    foreach my $method (@{$attr->associated_methods}) {
-      $method->{body} = $name->can($method->name);
+  unless ($am_role) {
+    foreach my $attr (@attrs) {
+      foreach my $method (@{$attr->associated_methods}) {
+        $method->{body} = $name->can($method->name);
+      }
     }
   }
   $DID_INJECT{$name} = 1;
index 5b3761f..71ee793 100644 (file)
@@ -22,6 +22,9 @@ sub import {
     })->generate_method($target, $name, \%spec);
     $INFO{$target}{attributes}{$name} = \%spec;
   };
+  if ($INC{'Moo/HandleMoose.pm'}) {
+    Moo::HandleMoose::inject_fake_metaclass_for($target);
+  }
   goto &Role::Tiny::import;
 }
 
index b89b6b3..75400e5 100644 (file)
@@ -14,4 +14,14 @@ is($attr->get_read_method_ref->body, Foo->can('one'), 'Right method');
 
 is(Foo->new(one => 1, THREE => 3)->one, 1, 'Accessor still works');
 
+$meta = Moose::Meta::Class->initialize('Spoon');
+
+$meta->superclasses('Moose::Object');
+
+Moose::Util::apply_all_roles($meta, 'Bar');
+
+my $spoon = Spoon->new(four => 4);
+
+is($spoon->four, 4, 'Role application ok');
+
 done_testing;