diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-09-14 14:20:07 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-09-14 22:29:47 -0700 |
commit | 37b0b3b2e3fecf62fbb5a9c784ad24707e8d3581 (patch) | |
tree | 9d0f11f2160440fe168a5c0a62a2c8f1de04b691 /gv.c | |
parent | 0308a534a635b8c34297657046d32a3f05818821 (diff) | |
download | perl-37b0b3b2e3fecf62fbb5a9c784ad24707e8d3581.tar.gz |
Make SUPER::method respect method changes in moved pkg
->SUPER::method calls inside the Foo package cache the method for
reuse inside the stash Foo::SUPER.
Before the call, @Foo::SUPER::ISA is set to "Foo", so that those
caches will be invalidated properly. (@ISA has the magic to make that
work.) The actual value in @Foo::SUPER::ISA unused.
Now we have two types of package names. If you alias the Foo package
and then clobber the original entry:
*Bar:: = *Foo::;
undef *Foo::;
__PACKAGE__ and HvNAME will return Foo still, but HvENAME (the effec-
tive name) will return Bar, because that is where the package is to be
found.
As of the previous commit, the package used for ISA is based on the
effective name, Bar::SUPER in this case.
But @Bar::SUPER::ISA is still set to Foo. So even if we make changes
to methods inherited by what is now the Bar package, a previous method
cached in *Bar::SUPER::method will be reused.
BEGIN {
*Bar:: = *Foo::;
undef *Foo::;
}
package Bar;
@ISA = 'Baz';
*Baz::m = sub { "method 1" };
anthying->SUPER::m;
undef *Baz::m;
*Baz::m = sub { "method 2" };
warn anything->SUPER::m;
__END__
method 1 at - line 11.
Diffstat (limited to 'gv.c')
-rw-r--r-- | gv.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -921,7 +921,7 @@ S_gv_get_super_pkg(pTHX_ const char* name, I32 namelen, U32 flags) GvMULTI_on(gv); sv_magic(MUTABLE_SV(superisa), MUTABLE_SV(gv), PERL_MAGIC_isa, NULL, 0); av_push(superisa, newSVhek(CopSTASH(PL_curcop) - ? HvNAME_HEK(CopSTASH(PL_curcop)) : NULL)); + ? HvENAME_HEK(CopSTASH(PL_curcop)) : NULL)); return stash; } |