summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-09-20 21:24:02 -0700
committerFather Chrysostomos <sprout@cpan.org>2010-09-20 21:24:02 -0700
commitaf9838cc2fa3350e15e88a27008899ae3a3afdb6 (patch)
tree8312e06f5b3a831c414acd68fe51ce7c029c4c44 /t
parentebcfa0534aa7072c0353af79a1e3d7e87678e73e (diff)
downloadperl-af9838cc2fa3350e15e88a27008899ae3a3afdb6.tar.gz
[perl #19078] wrong match order inside replacement
$ perl -le '$_="CCCGGG"; s!.!@a{print("[$&]"),/./}!g' [C] [C] [C] [C] [C] [C] What’s happening is that the s/// does not reset PL_curpm for each iteration, because it doesn’t usually have to. The RHS’s scoping takes care of it most of the time. This happens with the /e modifier and with @{...}. In this example, though, we have a subscript, not a block. This sub- script is in the same scope as the s/// itself. The assumption that the substitution operator will never have to reset PL_curpm itself appears to be incorrect. This fixes it.
Diffstat (limited to 't')
-rw-r--r--t/re/subst.t24
1 files changed, 23 insertions, 1 deletions
diff --git a/t/re/subst.t b/t/re/subst.t
index 91c757a8a5..9b5fd61c63 100644
--- a/t/re/subst.t
+++ b/t/re/subst.t
@@ -7,7 +7,7 @@ BEGIN {
}
require './test.pl';
-plan( tests => 170 );
+plan( tests => 172 );
# Stolen from re/ReTest.pl. Can't just use the file since it doesn't support
# like() and it conflicts with test.pl
@@ -724,3 +724,25 @@ fresh_perl_is( '$_="abcef"; s/bc|(.)\G(.)/$1 ? "[$1-$2]" : "XX"/ge; print' => 'a
$string =~ s/./\777/;
is($string, chr 0x1FF, "Verify that handles s/foo/\\777/");
}
+
+# Scoping of s//the RHS/ when there is no /e
+# Tests based on [perl #19078]
+{
+ local *_;
+ my $output = ''; my %a;
+ no warnings 'uninitialized';
+
+ $_="CCCGGG";
+ s!.!<@a{$output .= ("$&"),/[$&]/g}>!g;
+ $output .= $_;
+ is(
+ $output, "CCCGGG< >< >< >< >< >< >",
+ 's/// sets PL_curpm for each iteration even when the RHS has set it'
+ );
+
+ s/C/$a{m\G\}/;
+ is(
+ "$&", G =>
+ 'Match vars reflect the last match after s/pat/$a{m|pat|}/ without /e'
+ );
+}