diff options
author | Tony Cook <tony@develop-help.com> | 2009-07-18 14:49:04 -0500 |
---|---|---|
committer | Craig A. Berry <craigberry@mac.com> | 2009-07-18 17:16:31 -0500 |
commit | 26d68d86a346a9cd3eddb7ee18bfaa50db17b7f0 (patch) | |
tree | 44dc8fb4598766ec9f1f67b8a1fecef4242bf54b | |
parent | ce4f4fe21306fe15b2fbafac14eb81691d0b304a (diff) | |
download | perl-26d68d86a346a9cd3eddb7ee18bfaa50db17b7f0.tar.gz |
mro::method_changed_in(..) ignores AUTOLOAD (RT #60220)
Patch modified to use a boolean rather than an integer for tracking
mro changes in S_glob_assign_ref and test fixed not to warn.
URL: http://rt.perl.org/rt3/Ticket/Display.html?id=60220
From the bug report:
-----------------------------------------------------------------
When creating a subclass dynamically, and when adding
AUTOLOAD dynamically into the parent class, then that
AUTOLOAD is not seen in the method cache, even after
a call to "mro::method_changed_in('Parent')".
It only appears in the method cache after a call
to mro::invalidate_all_method_caches().
The attached test file demonstrates the problem.
This was detected while trying to solve bug 40159 in DBIx::DataModel.
-----------------------------------------------------------------
Message-ID: <20081031132021.GA21341@mars.tony.develop-help.com>
-rw-r--r-- | sv.c | 4 | ||||
-rw-r--r-- | t/mro/basic.t | 17 |
2 files changed, 20 insertions, 1 deletions
@@ -3656,6 +3656,7 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) SV **location; U8 import_flag = 0; const U32 stype = SvTYPE(sref); + bool mro_changes = FALSE; PERL_ARGS_ASSERT_GLOB_ASSIGN_REF; @@ -3676,6 +3677,8 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) goto common; case SVt_PVAV: location = (SV **) &GvAV(dstr); + if (strEQ(GvNAME((GV*)dstr), "ISA")) + mro_changes = TRUE; import_flag = GVf_IMPORTED_AV; goto common; case SVt_PVIO: @@ -3754,6 +3757,7 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) SvREFCNT_dec(dref); if (SvTAINTED(sstr)) SvTAINT(dstr); + if (mro_changes) mro_isa_changed_in(GvSTASH(dstr)); return; } diff --git a/t/mro/basic.t b/t/mro/basic.t index e06622649e..8568517244 100644 --- a/t/mro/basic.t +++ b/t/mro/basic.t @@ -3,7 +3,7 @@ use strict; use warnings; -require q(./test.pl); plan(tests => 40); +require q(./test.pl); plan(tests => 42); require mro; @@ -233,3 +233,18 @@ is(eval { MRO_N->testfunc() }, 123); is($stk_obj->foo(3), 6); } +{ + { + # assigning @ISA via arrayref to globref RT 60220 + package P1; + sub new { bless {}, shift } + + package P2; + } + *{P2::ISA} = [ 'P1' ]; + my $foo = P2->new; + ok(!eval { $foo->bark }, "no bark method"); + no warnings 'once'; # otherwise it'll bark about P1::bark used only once + *{P1::bark} = sub { "[bark]" }; + is(scalar eval { $foo->bark }, "[bark]", "can bark now"); +} |