Subject: | Nested roles not flagging conflicts |
Date: | Tue, 30 Aug 2016 06:34:42 +0000 |
To: | "bug-Moose [...] rt.cpan.org" <bug-Moose [...] rt.cpan.org> |
From: | "Pansino, Thomas" <thomas.pansino [...] intel.com> |
I have some code similar to the following:
Show quoted text
> ls
BaseRole.pm ChildRoleA.pm ChildRoleB.pm MyClass.pm test.pl
====== BaseRole.pm ======
package BaseRole;
use Moose::Role;
sub foo {
print("Calling BaseRole::foo\n");
}
1;
====== ChildRoleA.pm ======
package ChildRoleA;
use Moose::Role;
with 'BaseRole';
sub bar {
print("Calling ChildRoleA::bar\n");
}
1;
====== ChildRoleB.pm ======
package ChildRoleB;
use Moose::Role;
with 'BaseRole';
requires 'bar';
sub foo {
print("Calling ChildRoleB::foo\n");
}
1;
====== MyClass.pm ======
package MyClass;
use Moose;
with 'ChildRoleA';
with 'ChildRoleB';
__PACKAGE__->meta()->make_immutable();
1;
====== test.pl ======
#!/usr/bin/env perl
use v5.14.1;
use strict;
use warnings;
use MyClass;
my $class = MyClass->new();
$class->foo();
$class->bar();
Running test.pl produces the following output:
Calling BaseRole::foo
Calling ChildRoleA::bar
When I originally wrote this, I was hoping that the definition of ChildRoleB::foo would override BaseRole::foo since the with call to ChildRoleB comes after the with call to ChildRoleA.
After quite a bit of manual reading and Internet research, I realized Moose roles don't really have inheritance like that. The only overriding that's valid would have been a definition for foo in MyClass, therefore having two definitions for foo in two different roles should actually have been flagged as a conflict when MyClass was composed.
So first thing - is my understanding correct? You can only override a method from a role with a definition in a composing class? All other conflicting definitions in roles needs to be dealt with via exclusion or aliasing?
If so, then the real question is, why is this not being flagged as a conflict? I tested and it does flag correctly in version 2.08, but not in 2.16 if I do the with as two separate statements like it is in my example. If I change it to be a single with call though, it works as expected.
My guess is something changed in Moose::Util::apply_all_roles between these two versions. Thoughts?