On 28 March 2013 16:41, Jesse Luehrs <d...@tozt.net> wrote: > 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.
Whoah! What? So when I want to compose, say a and b and write my own 'result' which will combine a's result and b's result, what am I supposed to do? I'd always been under the impression that when I do: with qw(a b);\ I'm expressing the expectation that there are no conflicts between those two roles and I want an (ideally compile time) error if they do conflict, and I can get in and fix it through judicious use of excludes (and possibly an alias or two). If I want the order of composition to matter, then I can do with 'a'; with 'b'; For the life of me I can't see how this change can be called a good idea. > 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). That's certainly not what I'm after. But I do want to retain the difference between 'with qw(a b)' and 'with q(a); with q(b);' thank you very much. Who cooked up this idea?