From: Tony Cook Date: Thu, 18 Feb 2010 09:59:33 +0000 (+1100) Subject: rt #72866 - add magic to arrayrefs assigned to *Foo::ISA X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d851b1227a19f97a94b5fca3f346e709d37be33b;p=p5sagit%2Fp5-mst-13.2.git rt #72866 - add magic to arrayrefs assigned to *Foo::ISA The fix for rt #60220 (26d68d86) updated the isa cache when an arrayref was assigned to some *ISA, but didn't add the magic to the new @ISA to catch any further updates to it. Add the magic, and tests. --- diff --git a/sv.c b/sv.c index 53e3410..2f429cc 100644 --- a/sv.c +++ b/sv.c @@ -3685,7 +3685,6 @@ 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; @@ -3706,8 +3705,6 @@ 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: @@ -3781,12 +3778,15 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) && CopSTASH_ne(PL_curcop, GvSTASH(dstr))) { GvFLAGS(dstr) |= import_flag; } + if (stype == SVt_PVAV && strEQ(GvNAME((GV*)dstr), "ISA")) { + sv_magic(sref, dstr, PERL_MAGIC_isa, NULL, 0); + mro_isa_changed_in(GvSTASH(dstr)); + } break; } 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 a4d3015..fbd3a6d 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 => 44); +require q(./test.pl); plan(tests => 48); require mro; @@ -250,6 +250,28 @@ is(eval { MRO_N->testfunc() }, 123); } { + # assigning @ISA via arrayref then modifying it RT 72866 + { + package Q1; + sub foo { } + + package Q2; + sub bar { } + + package Q3; + } + push @Q3::ISA, "Q1"; + can_ok("Q3", "foo"); + *Q3::ISA = []; + push @Q3::ISA, "Q1"; + can_ok("Q3", "foo"); + *Q3::ISA = []; + push @Q3::ISA, "Q2"; + can_ok("Q3", "bar"); + ok(!Q3->can("foo"), "can't call foo method any longer"); +} + +{ # test mro::method_changed_in my $count = mro::get_pkg_gen("MRO_A"); mro::method_changed_in("MRO_A");