This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make pp_multideref handle local $::{subref}
authorFather Chrysostomos <sprout@cpan.org>
Sun, 24 Sep 2017 23:48:48 +0000 (16:48 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 8 Oct 2017 20:06:06 +0000 (13:06 -0700)
Based on a patch by Nicholas R.

pp_hot.c
t/op/local.t

index f356d09..ea91847 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2997,7 +2997,7 @@ PP(pp_multideref)
                         }
                         else {
                             if (localizing) {
-                                if (HvNAME_get(hv) && isGV(sv))
+                                if (HvNAME_get(hv) && isGV_or_RVCV(sv))
                                     save_gp(MUTABLE_GV(sv),
                                         !(PL_op->op_flags & OPf_SPECIAL));
                                 else if (preeminent) {
index e88798a..df1413a 100644 (file)
@@ -5,7 +5,7 @@ BEGIN {
     require './test.pl';
     set_up_inc(  qw(. ../lib) );
 }
-plan tests => 315;
+plan tests => 319;
 
 my $list_assignment_supported = 1;
 
@@ -670,6 +670,8 @@ is($@, "");
 
        sub f1 { "f1" }
        sub f2 { "f2" }
+       sub f3 { "f3" }
+       sub f4 { "f4" }
 
        no warnings "redefine";
        {
@@ -682,6 +684,22 @@ is($@, "");
                ::ok(f1() eq "h1", "localised sub via stash");
        }
        ::ok(f1() eq "f1", "localised sub restored");
+       # Do that test again, but with a different glob, to make sure that
+       # localisation via multideref can handle a subref in a stash.
+       # (The local *f1 above will have ensured that we have a full glob,
+       # not a sub ref.)
+       {
+               local $Other::{"f3"} = sub { "h1" };
+               ::ok(f3() eq "h1", "localised sub via stash");
+       }
+       ::ok(f3() eq "f3", "localised sub restored");
+       # Also, we need to test pp_helem, which we can do by using a more
+       # complex subscript.
+       {
+               local $Other::{${\"f4"}} = sub { "h1" };
+               ::ok(f4() eq "h1", "localised sub via stash");
+       }
+       ::ok(f4() eq "f4", "localised sub restored");
        {
                local @Other::{qw/ f1 f2 /} = (sub { "j1" }, sub { "j2" });
                ::ok(f1() eq "j1", "localised sub via stash slice");