On Apr 8, 2012, at 6:25 PM, Poul Henning Sørensen wrote:
>
> On 2012.04.08, at 21:31, Ovid wrote:
>
>> Hi all,
>>
>> I'm wondering if this is a known bug or a misunderstanding on my part (I
>> assume the latter):
>>
>> use 5.10.0;
>> { package Role::A; use Moose::Role; with 'Role::C'; }
>> { package Role::B; use Moose::Role; with 'Role::C'; }
>> { package Role::C; use Moose::Role; with 'Role::D'; }
>> {
>> package Role::D;
>> use Moose::Role;
>>
>> sub foo {
>> my $proto = shift;
>> my $class = ref $proto // $proto;
>> return "$class\::foo";
>> }
>> }
>> package Consume;
>> use Moose;
>> with qw(Role::A Role::B);
>> say Moose->VERSION;
>> say Consume->foo;
>>
>> That prints out:
>>
>> 2.0402
>> Can't locate object method "foo" via package "Consume" at roles.pl line
>> 19.
>>
>> Given that Role::C uses Role::D and the latter provides the 'foo()' method,
>> that method should be provided to both Role::A and Role::B since they each
>> consume Role::C. When consuming those roles, the Consume class should then
>> have the 'foo()' method, but it does not.
>>
>> Did I misunderstand something? (For the curious, my Role::Basic module has
>> the same bug).
>>
>
> To me it seems you're having a "conflict" - foo() is available in both
> Role::A and Role::B, and you the consuming class Consume should resolve it by
> implementing the method foo() itself. It can use combinations of method
> exclusion and aliasing.
Actually, foo() shouldn't conflict since it is the same underlying CODE
reference. I suspect that is actually where things are getting confused.
- Stevan
>
> Now, in your (short) example, Role::D::foo acts the same way, but imaging
> foo() invoked something that was different in Role::A and Role::B, then
> Consume's foo() has to decide what is the wanted version of foo()...
>
> Hope that this helps.
>
> regards
> Poul Sørensen
> Basefarm AS