summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scope.c21
-rw-r--r--t/mro/basic.t19
2 files changed, 34 insertions, 6 deletions
diff --git a/scope.c b/scope.c
index c4a2222e75..31b990dec5 100644
--- a/scope.c
+++ b/scope.c
@@ -286,14 +286,21 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty)
if (empty) {
GP *gp = Perl_newGP(aTHX_ gv);
HV * const stash = GvSTASH(gv);
-
- if (GvCVu(gv) && stash && HvENAME(stash))
- mro_method_changed_in(GvSTASH(gv)); /* taking a method out of circulation ("local")*/
+ bool isa_changed = 0;
+
+ if (stash && HvENAME(stash)) {
+ if (GvNAMELEN(gv) == 3 && strnEQ(GvNAME(gv), "ISA", 3))
+ isa_changed = TRUE;
+ else if (GvCVu(gv))
+ /* taking a method out of circulation ("local")*/
+ mro_method_changed_in(stash);
+ }
if (GvIOp(gv) && (IoFLAGS(GvIOp(gv)) & IOf_ARGV)) {
gp->gp_io = newIO();
IoFLAGS(gp->gp_io) |= IOf_ARGV|IOf_START;
}
GvGP_set(gv,gp);
+ if (isa_changed) mro_isa_changed_in(stash);
}
else {
gp_ref(GvGP(gv));
@@ -860,9 +867,13 @@ Perl_leave_scope(pTHX_ I32 base)
gv = MUTABLE_GV(SSPOPPTR);
gp_free(gv);
GvGP_set(gv, (GP*)ptr);
- /* putting a method back into circulation ("local")*/
- if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvENAME_get(hv))
+ if ((hv=GvSTASH(gv)) && HvENAME_get(hv)) {
+ if (GvNAMELEN(gv) == 3 && strnEQ(GvNAME(gv), "ISA", 3))
+ mro_isa_changed_in(hv);
+ else if (GvCVu(gv))
+ /* putting a method back into circulation ("local")*/
gv_method_changed(gv);
+ }
SvREFCNT_dec(gv);
break;
case SAVEt_FREESV:
diff --git a/t/mro/basic.t b/t/mro/basic.t
index cc1386c5f4..ab34fc2567 100644
--- a/t/mro/basic.t
+++ b/t/mro/basic.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-BEGIN { require q(./test.pl); } plan(tests => 55);
+BEGIN { require q(./test.pl); } plan(tests => 59);
require mro;
@@ -353,3 +353,20 @@ is(eval { MRO_N->testfunc() }, 123);
eval { local *Detached::method };
is $@, "", 'localising gv-with-cv belonging to detached package';
}
+
+{
+ # *ISA localisation
+ @il::ISA = "ilsuper";
+ sub ilsuper::can { "puree" }
+ sub il::tomatoes;
+ {
+ local *il::ISA;
+ is +il->can("tomatoes"), \&il::tomatoes, 'local *ISA';
+ }
+ is "il"->can("tomatoes"), "puree", 'local *ISA unwinding';
+ {
+ local *il::ISA = [];
+ is +il->can("tomatoes"), \&il::tomatoes, 'local *ISA = []';
+ }
+ is "il"->can("tomatoes"), "puree", 'local *ISA=[] unwinding';
+}