Class::MOP::_definition_context(),
));
+__PACKAGE__->meta->add_attribute('shadowing_prohibited' => (
+ init_arg => '-prohibit_shadowing',
+ reader => 'is_shadowing_prohibited',
+ default => sub { 0 },
+ Class::MOP::_definition_context(),
+));
+
sub new {
my ($class, %params) = @_;
$class->_new(\%params);
my $class_method = $class->get_method($method_name);
- next if $class_method && $class_method->body != $method->body;
+ if ( $class_method && $class_method->body != $method->body ) {
+
+ if ( $self->is_shadowing_prohibited ) {
+ $class->throw_error(
+ "Shadowing is prohibited but both ".$class->name." and ".$role->name." have a method ${method_name}"
+ );
+ }
+ next;
+ }
$class->add_method(
$method_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.
+ # for classes, unless shadowing is explicitly prohibited
+
+ if ( $self->is_shadowing_prohibited ) {
+
+ $role2->add_conflicting_method(
+ name => $method_name,
+ roles => [ $role1->name, $role2->name ],
+ );
+ }
}
else {
$role2->add_method(
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Fatal;
+
+{
+ package Role1;
+
+ use Moose::Role;
+
+ sub foo { }
+}
+
+{
+ package Role2;
+
+ use Moose::Role;
+
+ with 'Role1', { -prohibit_shadowing => 1 };
+
+ sub foo { }
+}
+
+{
+ package Class1;
+
+ use Moose;
+
+ ::ok(
+ ::exception { with 'Role1', { -prohibit_shadowing => 1 } },
+ 'Shadowing prohibited role->class'
+ );
+
+ sub foo { }
+}
+
+{
+ package Class2;
+
+ use Moose;
+
+ ::ok(
+ ::exception { with 'Role2' },
+ 'Shadowing prohibited role->role'
+ );
+}
+
+done_testing;