On Wed, Jul 15, 2009 at 11:24:11AM -0700, Ovid wrote:
> Consider the following code. Now that the role provides an attribute named
> "counter" and the class using the role provides a method of the same name.
> The methods are not semantically equivalent, so I had two expectations,
> possibly due to me misunderstanding Moose:
>
> 1. The class method would silently override the role attribute.
> 2. This code would break horribly.
>
> #!/usr/bin/env perl -l
>
> {
> package MyRole;
> use Moose::Role;
> has counter => ( is => 'rw', default => 0 );
>
> sub inc {
> my $self = shift;
> $self->counter( $self->counter + 1 );
> return $self->counter;
> }
> }
> {
> package Foo;
> use Moose;
> with 'MyRole';
> sub counter { 'this is the counter' }
> }
> my $foo = Foo->new;
> print $foo->inc for 1 .. 5;
> print $foo->counter;
>
> However, my expectations were wrong. Here's the output when run:
>
> 1
> 2
> 3
> 4
> 5
> 5
>
>
> In other words, the class's counter() method was silently discarded, denying
> the class the ability to control its behavior.
We actually just discussed this in #moose yesterday, it's mostly an
artifact of the role implementation not really being quite complete -
attributes in roles don't *really* exist until they're added to a class,
and at that point have no concept that they actually came from a role.
This is hopefully something that will be addressed when the attributes
in roles system is redone (I think Yuval has a plan for this?)
Jesse