$ 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.
(void)ReREFCNT_inc(rx);
cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
rxres_save(&cx->sb_rxres, rx);
+ PL_curpm = pm;
RETURNOP(pm->op_pmstashstartu.op_pmreplstart);
}
}
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
$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'
+ );
+}