Re: Superclass method modifiers don't run when attribute is extended/modified
[email protected] (Bernardo Rechea)
| Newsgroups | perl.moose |
|---|---|
| Message-ID | <[email protected]> |
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');