On Thu, Mar 28, 2013 at 09:20:55AM -0700, Ovid wrote: > Ouch! You're right. My apologies for the confusion. The examples should be > this: > > use 5.01000; > { package a; use Moose::Role; sub result { 'a' } } > > { package b; use Moose::Role; } > { package c; use Moose::Role; with qw(a b); sub result { 'c' } } > { package d; use Moose::Role; with qw(c); } > { > package Consumer; use Moose; > with 'd'; > } > say Consumer->new->result; > > Versus: > > use 5.01000; > { package a; use Moose::Role; with qw(b c); sub result { 'a' } } > { package b; use Moose::Role; } > { package c; use Moose::Role; sub result { 'c' } } > { package d; use Moose::Role; with qw(a); } > > { > package Consumer; use Moose; > with 'd'; > } > say Consumer->new->result; > > Only the order of role consumption is changed, but the behavior is now > different.
I can't really agree here that "only the order of role consumption is changed". I certainly wouldn't have the expectation that those two code snippets would necessarily produce the same result. The reason for this change is to bring role composition in roles into line with how role composition in classes works. For instance, here: package a; use Moose::Role; sub result { 'a' } package b; use Moose; sub result { 'b' } This has always worked without error. On the other hand, this: package a; use Moose::Role; sub result { 'a' } package b; use Moose::Role; sub result { 'b' } has historically been a conflict error, and one that has bit me (and several other people) on several occasions. I have never meant anything other than the behavior that happens in the class case, so I don't see why extending that behavior to the role case is a problem. (Or is it your opinion that the first snippet there should also be a conflict?) In general, I can't really understand why the behavior for roles and classes should be different in this sense. A role consuming another role is a different operation from role summation, and one that I think should behave more similarly to a class consuming a role. Note that this is still a conflict: { package a; use Moose::Role; sub result { 'a' } } { package b; use Moose::Role; } { package c; use Moose::Role; sub result { 'c' } } { package d; use Moose::Role; with qw(a b c); } The other benefit here is that with this change, alias and excludes become completely unnecessary, and can hopefully be deprecated. If what you're after here is a way to disallow all forms of silent method overriding, I think this is better done in an extension (since it would have to catch conflicts in inheritance situations as well anyway). -doy