On Thu, Mar 28, 2013 at 05:36:23PM +0000, Piers Cawley wrote:
> 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?

You would just do that, the same way as if it was in a class:

  package Role1;
  use Moose::Role;
  sub result { 'a' }

  package Role2;
  use Moose::Role;
  sub result { 'b' }

  package Combined;
  use Moose::Role;
  with qw(Role1 Role2);
  sub result {
      my $self = shift;
      return $self->a::result . $self->b::result;
  }

This has always worked when Combined is a class, now it just also works
when Combined is a role.

That said, I have yet to see a single case in the entire time I've been
using Moose where "combining" is an answer that makes any kind of sense
for resolving a role conflict.

> 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).

No, overriding is a perfectly valid way to resolve conflicts, and always
has been. alias and excludes are only important to fix cases where this
isn't possible, and this change should remove the last of those.

> 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.

It doesn't have anything at all to do with the difference between
"with 'a', 'b'" and "with 'a'; with 'b';".

-doy

Reply via email to