From af9838cc2fa3350e15e88a27008899ae3a3afdb6 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Mon, 20 Sep 2010 21:24:02 -0700 Subject: [perl #19078] wrong match order inside replacement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $ 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. --- t/re/subst.t | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 't/re/subst.t') 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' + ); +} -- cgit v1.2.1