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');
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.