change role-to-role application to allow method shadowing
Matt S Trout [Thu, 19 Apr 2012 21:11:54 +0000 (21:11 +0000)]
lib/Moose/Meta/Role/Application/ToRole.pm
t/roles/method_aliasing_in_composition.t
t/roles/method_exclusion_in_composition.t
t/roles/more_alias_and_exclude.t
t/roles/overriding.t

index e8ab886..97ce038 100644 (file)
@@ -85,12 +85,9 @@ sub apply_methods {
             if (   $role2_method
                 && $role2_method->body != $method->body ) {
 
-                # method conflicts between roles result in the method becoming
-                # a requirement
-                $role2->add_conflicting_method(
-                    name  => $method_name,
-                    roles => [ $role1->name, $role2->name ],
-                );
+                # method conflicts between roles used to result in the method
+                # becoming a requirement but now are permitted just like
+                # for classes, hence no code in this branch anymore.
             }
             else {
                 $role2->add_method(
index c6146a7..c392eae 100644 (file)
@@ -57,7 +57,7 @@ ok(My::Class->meta->has_method($_), "we have a $_ method") for qw(foo baz bar ro
 }
 
 ok(My::OtherRole->meta->has_method($_), "we have a $_ method") for qw(foo baz role_bar);
-ok(My::OtherRole->meta->requires_method('bar'), '... and the &bar method is required');
+ok(!My::OtherRole->meta->requires_method('bar'), '... and the &bar method is not required');
 ok(!My::OtherRole->meta->requires_method('role_bar'), '... and the &role_bar method is not required');
 
 {
index 64c3605..656b437 100644 (file)
@@ -37,7 +37,7 @@ ok(!My::Class->meta->has_method('bar'), '... but we excluded bar');
 ok(My::OtherRole->meta->has_method($_), "we have a $_ method") for qw(foo bar baz);
 
 ok(!My::OtherRole->meta->requires_method('foo'), '... and the &foo method is not required');
-ok(My::OtherRole->meta->requires_method('bar'), '... and the &bar method is required');
+ok(!My::OtherRole->meta->requires_method('bar'), '... and the &bar method is not required');
 
 {
     package Foo::Role;
index 62d3098..41fd795 100644 (file)
@@ -65,4 +65,26 @@ is($c->foo_gorch, 'Foo::gorch', '... got the right method');
 is($c->baz_foo, 'Baz::foo', '... got the right method');
 is($c->baz_bar, 'Baz::bar', '... got the right method');
 
+{
+    package Splunk;
+
+    use Moose::Role;
+
+    sub baz   { 'Splunk::baz'   }
+    sub gorch { 'Splunk::gorch' }
+
+    ::is(::exception { with 'Foo' }, undef, 'role to role application works');
+
+    package My::Class2;
+
+    use Moose;
+
+    ::is(::exception { with 'Splunk' }, undef, 'and the role can be consumed');
+}
+
+is(My::Class2->foo, 'Foo::foo', '... got the right method');
+is(My::Class2->bar, 'Foo::bar', '... got the right method');
+is(My::Class2->baz, 'Splunk::baz', '... got the right method');
+is(My::Class2->gorch, 'Splunk::gorch', '... got the right method');
+
 done_testing;
index 6f7d11b..cc4027d 100644 (file)
@@ -48,38 +48,26 @@ is( Class::A->new->xxy, "Role::B::xxy",  "... got the right xxy method" );
 
 {
     # check that when a role is added to another role
-    # and they conflict and the method they conflict
-    # with is then required.
+    # that the consumer's method shadows just like for classes.
 
-    package Role::A::Conflict;
+    package Role::A::Shadow;
     use Moose::Role;
 
     with 'Role::A';
 
-    sub bar { 'Role::A::Conflict::bar' }
+    sub bar { 'Role::A::Shadow::bar' }
 
-    package Class::A::Conflict;
-    use Moose;
-
-    ::like( ::exception {
-        with 'Role::A::Conflict';
-    }, qr/Due to a method name conflict in roles 'Role::A' and 'Role::A::Conflict', the method 'bar' must be implemented or excluded by 'Class::A::Conflict'/, '... did not fufill the requirement of &bar method' );
-
-    package Class::A::Resolved;
+    package Class::A::Shadow;
     use Moose;
 
     ::is( ::exception {
-        with 'Role::A::Conflict';
+        with 'Role::A::Shadow';
     }, undef, '... did fufill the requirement of &bar method' );
-
-    sub bar { 'Class::A::Resolved::bar' }
 }
 
-ok(Role::A::Conflict->meta->requires_method('bar'), '... Role::A::Conflict created the bar requirement');
-
-can_ok( Class::A::Resolved->new, qw(bar) );
+can_ok( Class::A::Shadow->new, qw(bar) );
 
-is( Class::A::Resolved->new->bar, 'Class::A::Resolved::bar', "... got the right bar method" );
+is( Class::A::Shadow->new->bar, 'Role::A::Shadow::bar', "... got the right bar method" );
 
 {
     # check that when two roles are composed, they conflict
@@ -131,24 +119,23 @@ ok(!Role::F->meta->requires_method('foo'), '... Role::F fufilled the &foo requir
     # by a role, but also new ones can be
     # created just as easily ...
 
-    package Role::D::And::E::Conflict;
+    package Role::D::And::E::NoConflict;
     use Moose::Role;
 
     ::is( ::exception {
         with qw(Role::D Role::E); # conflict between 'foo's here
-    }, undef, "... define role Role::D::And::E::Conflict" );
+    }, undef, "... define role Role::D::And::E::NoConflict" );
 
-    sub foo { 'Role::D::And::E::Conflict::foo' }  # this overrides ...
+    sub foo { 'Role::D::And::E::NoConflict::foo' }  # this overrides ...
 
-    # but these conflict
-    sub xxy { 'Role::D::And::E::Conflict::xxy' }
-    sub bar { 'Role::D::And::E::Conflict::bar' }
+    sub xxy { 'Role::D::And::E::NoConflict::xxy' }  # and so do these ...
+    sub bar { 'Role::D::And::E::NoConflict::bar' }
 
 }
 
-ok(!Role::D::And::E::Conflict->meta->requires_method('foo'), '... Role::D::And::E::Conflict fufilled the &foo requirement');
-ok(Role::D::And::E::Conflict->meta->requires_method('xxy'), '... Role::D::And::E::Conflict adds the &xxy requirement');
-ok(Role::D::And::E::Conflict->meta->requires_method('bar'), '... Role::D::And::E::Conflict adds the &bar requirement');
+ok(!Role::D::And::E::NoConflict->meta->requires_method('foo'), '... Role::D::And::E::NoConflict fufilled the &foo requirement');
+ok(!Role::D::And::E::NoConflict->meta->requires_method('xxy'), '... Role::D::And::E::NoConflict fulfilled the &xxy requirement');
+ok(!Role::D::And::E::NoConflict->meta->requires_method('bar'), '... Role::D::And::E::NoConflict fulfilled the &bar requirement');
 
 {
     # conflict propagation