On Fri, Nov 14, 2008 at 6:28 PM, Stevan Little via RT <[EMAIL PROTECTED] > wrote:
> <URL: http://rt.cpan.org/Ticket/Display.html?id=40848 > > > I do not consider this a bug, an annoyance maybe, but not a bug. 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. > > > 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! > > > 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? > > > 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. > > > 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. > > > >