Stevan Little wrote: > The "after" modifier is applied to accessor generated in the original > class, it is not re-applied for each subclass. When you redefine or > extend the "attr1" attribute in your subclasses you are defining a > completely new "attr1" accessor and therefore overriding the original > one. Remember that "after" is applied to the method specifically, it > does not care if the method was written by you, or by an attribute > and so it will do nothing special if its applied to the accessor.
Thanks for clearing that up, Stevan. I think I had that expectation because up until now I had done and seen two things: a) if one doesn't change an attribute at all in a subclass (except, perhaps, to provide a modifier to its accessor), its modifier(s) in its superclasses still run. b) if an attribute whose accessor doesn't have modifiers in the superclasses is extended, only those properties/options of the attribute that are explicitly modified change, and everything else from the superclass still applies. So I never had in mind (even though I had read about it) the implications of - redefining an attribute in a subclass: everything related to the attribute (accessor methods, etc.) is generated anew for the subclass; nor of - extending an attribute in a subclass: internally, the attribute is first cloned (thereby making it "a completely new 'attr1'") and then the requested extensions or modifications are applied to the clone (or it works _as if_ that were the case?). In both cases, the accessor code refs are different than the superclass', etc. Now, when I both declared a modifier in the superclass _and_ redefined/extended an attribute, the implications had an effect I didn't expect... Anyway, all of the blabber above is just my way of digesting your answer in terms of my naive understanding of things. Hmm, perhaps it would be a start for a WTF entry? Oh, but wait, look at the second case in the code I sent (copied below). The 'att1' attribute is redefined with has 'att1' => (isa => 'Str'), and yet the 'after' modifiers of both parent and child classes are triggered (?!). Bernardo ============================================================================= #!/usr/bin/env perl { package Role1; use Moose::Role; has 'att1' => ( is => 'rw', isa => 'Any' ); } { package Foo; use Moose; with 'Role1'; after 'att1' => sub { my($self, $att1) = @_; print "In 'after att1' modifier in class Foo\n"; } } print "--- Class Foo::Bar redefines att1's 'isa' ---\n"; { package Foo::Bar; use Moose; extends 'Foo'; has 'att2' => ( is => 'rw' ); has 'att1' => ( isa => 'Str'); after 'att1' => sub { my($self, $att1) = @_; print "In 'after att1' modifier in class Foo::Bar\n"; } } $o = Foo::Bar->new(att1 => 'kk'); $o->att1('dummy');