On Fri, Nov 14, 2008 at 6:28 PM, Stevan Little via RT <bug-Moose@rt.cpan.org
Show quoted text> wrote:
Show quoted text
After looking a bit more deeply about how Moose handles attribute
inheritance, I tend to agree with you now. I was originally thinking the
'has +' notation modified the base class's attribute (but in a way only
visible to the derived class), but now I realize it just creates a new
attribute in the derived class with options copied from the base class, and
everything that comes with that.
Show quoted text>
>
> As you figured out, the +name syntax copies the superclass attribute and
> then installs it in the local
> class, overriding everything that was inherited. Because of this, +name
> should not be considered to be
> so magical as to know what you may and may not inherit. It is sort of
> "brute force" in that sense.
Awww...I like magic!
Show quoted text>
>
> My feeling is that the complexity of making it more magical and all the
> permutations of interactions that
> would result would be less intuitive and more difficult to work with and
> work around. As you discovered
> when you encountered this bug, what was actually happening was pretty
> obvious and simple, thus easier
> to work with and work around.
Fine. I would love to know a straightforward work-around though, that does
not drastically alter class structures. Would it be to much to ask for an
option to 'has +' that simply disables any accessor generation (and
provides/curries methods), that is totally *use-at-own-risk* and would
assume all the appropriate methods were installed in the base class?
Show quoted text>
>
> However, if you disagree with me, I am willing to discuss this in more
> detail, but please take it to the
> moose mailing list (moose@perl.org) so that the rest of the community can
> take part of it.
Ok I will CC my reply to this to the list.
Show quoted text>
>
> Thanks,
>
> - Stevan
>
>
>
>
> On Wed Nov 12 02:15:39 2008, MEGAMIC wrote:
> > I recently had had a need to use the 'has +$name' syntax to modify the
> > ISA option of an inherited attribute. It turned out that in the base
> > class, I had used 'before' to wrap an accessor. I noticed that when I
> > then called the accessor from an instance of my extended class, the
> > before routine was not being called.
> >
> > The issue is obviously that the 'has +$name' will re-install all the
> > accessors over again, effectively destroying any other methods that may
> > have been installed in their place from the base class, method-modifiers
> > such as before,after,etc. being prime examples.
> >
> > Note that this issue also affects MooseX::Attribute helpers, in that the
> > 'provides' and 'curries' handlers will re-install methods in the class,
> > again overwriting method modifiers from the base class. In fact, this is
> > really the situation I had experienced: I had 'provides' install a
> > 'get_thing' method on an attribute, which was wrapped by a 'before'
> > method, and was subsequently destroyed by the extended class' 'has'
> > method re-installing all the 'provides' methods.
> >
> > I think this qualifies as a bug, as it is really unexpected behavior,
> > 'before' methods are ordinarily carried through inheritance, and there
> > is nothing implicit in changing an attribute (say 'required') with 'has
> > +$name' which would suggest that all your method modifying get destroyed.
> >
> > The following code illustrates the problem:
> > package Foo;
> > use Moose;
> >
> > has name => (is => 'rw', isa => 'Str');
> >
> > before name => sub { warn "before\n" };
> >
> > 1;
> >
> > package Bar;
> > use Moose;
> >
> > extends 'Foo';
> >
> > has '+name' => (required => 0);
> >
> > 1;
> >
> > my $foo = new Foo;
> > my $bar = new Bar;
> >
> > $foo->name('bob'); // This prints 'before'...
> > $bar->name('jim'); // this doesnt.
>
>
>
>