The new /r flag
Perl 5.14 introduced a new feature for the substitution operator to return a modified string while leaving the original alone. Normally, the substitution operator changes the bound string (if it matches) and returns the count of the number of substitutions:
my $count = $string =~ s/PATTERN/REPLACEMENT/g;
If you didn't want to change the string, you had to create a new one, often leading to this idiom:
( my $new = $old ) =~ s/PATTERN/REPLACEMENT/g;
This way, $new
gets a copy and is actually the target of the s///
. Instead of that, you can use the new /r
flag. That idiom then changes to this similar, but different statement:
my $new = $old =~ s/PATTERN/REPLACEMENT/gr;
This binds to $old
and returns the modified string to store in $new
. Working out the precedence, it looks like the parentheses have shifted:
my $new = ( $old =~ s/PATTERN/REPLACEMENT/gr );
This turns out to be much more useful inside a map
, where it's easy to forget that you don't get the modified string back:
my @new = map { s/PATTERN/REPLACEMENT/g } @old;
After your @new
fills with 1
's and 0
's, you remember that you need a different last expression in the map
block:
my @new = map { s/PATTERN/REPLACEMENT/g; $_ } @old;
But then, you find out that @new
is the same as @old
because the s///
with the aliased $_
actually changes the original data. So, you expand the block a bit:
my @new = map { my $s = $_; $s =~ s/PATTERN/REPLACEMENT/g; $s } @old;
That's ugly. So, you upgrade to Perl 5.14 to get back to almost what you had before. Once you convince your entire company to upgrade, update all of your operating systems and packages, and reinstall all the modules, the /r
flag saves you a lot of hassle inside the block:
my @new = map { s/PATTERN/REPLACEMENT/rg } @old;
This is useful with printf
too, where you might want to modify a string just for the output, but leaving the original alone:
printf "%s %s\n",
s/PATTERN/REPLACEMENT/rg,
s/PATTERN2/REPLACEMENT/rg;
With the /r
flag, it's now convenient to have the s///
in the middle of larger expressions.