I guess it wasn't clear in my initial example code that
I'm creating a new closure for each attribute not just
aliasing the same sub.
$subclass->new_meth will set $AUTOLOAD to
"SUBCLASS::new_meth" so will install the closure there.
If later I call $other_subclass->new_meth
then I'll get another sub in OTHERSUBCLASS::new_meth.
package A;
sub AUTOLOAD {
my ($fn) = $AUTOLOAD =~ /^.*::(.+)$/;
return if $fn eq 'DESTROY';
*{$AUTOLOAD} = sub { print "$AUTOLOAD $fn"; };
goto &$AUTOLOAD;
}
package B;
@ISA = "A";
package C;
@ISA = "A";
package main;
$a = bless {}, 'A';
$b = bless {}, 'B';
$c = bless {}, 'C';
$a->shared; # call via baseclass first
$b->shared;
$c->shared;
$b->not_shared; # call via one subclas
$c->not_shared; # then another
$a->not_shared; # then base class
print "\nshared CODE refs:";
print $a->can('shared');
print $b->can('shared');
print $c->can('shared');
print "\nnot_shared CODE refs:";
print $a->can('not_shared');
print $b->can('not_shared');
print $c->can('not_shared');
Produces output:
perl -wl eg
A::shared shared
A::shared shared
A::shared shared
B::not_shared not_shared
C::not_shared not_shared
A::not_shared not_shared
shared CODE refs:
CODE(0x8105cb8)
CODE(0x8105cb8)
CODE(0x8105cb8)
not_shared CODE refs:
CODE(0x8105eb0)
CODE(0x8105db4)
CODE(0x8105e50)
So in the second case (which correspond to my usage)
you get same closure created and installed in 3 places.
|