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?

Reply via email to