Re: Superclass method modifiers don't run when attribute is extended/modified

[email protected] (Stevan Little)
Newsgroups perl.moose
Message-ID <[email protected]>
Bernardo,

On May 16, 2008, at 1:17 PM, Bernardo Rechea wrote:
> 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.

Nothing naive about it, your exactly correct in your understanding of  
things.

> Hmm, perhaps it would be a start for a WTF entry?

Sure, patches welcome, or stop by #moose for a commit bit.

> 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 (?!).

That is because ..

>     has 'att1' => (isa => 'Str'),

is not creating an accessor (no "is => 'rw'" or "is => 'ro'")

- Stevan

> 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.