New Features of Perl 5.14: Non-destructive Substitution
Perl 5.14 is now available. While this latest major release of Perl 5 brings with it many bugfixes, updates to the core libraries, and the usual performance improvements, it also includes a few nice new features.
One such feature is non-destructive substitution:
use 5.014;
my $greeting = 'Hello, world!';
# be more elite
say $greeting =~ tr/aeiou/4310V/r;
# then run away
say $greeting =~ s/Hello/Goodbye/r;
The new /r
modifier to the substitution and transliteration operators causes Perl to return the modified string, rather than modifying the original string in place. This replaces the idiomatic but unwieldy:
my $greeting = 'Hello, world!';
my ($leetgreet = $greeting) =~ tr/aeiou/4310V/;
This feature is even more useful for avoiding two common problems with substitutions in map
expressions:
my @modified = map { s/foo/BAR/ } @original;
Not only does the substitution modify the values of @original
in place, but the substitution returns a true value if the substitution succeeded and a false value otherwise. While that code looks correct, it’s very subtly wrong. The corrected version of this code in Perl 5.12 or earlier is:
my @modified = map { my $copy = $_; $copy =~ s/foo/BAR/; $copy } @original;
5.14 requires the addition of a single character to produce the intended behavior:
my @modified = map { s/foo/BAR/r } @original;
See perldoc perlop
for documentation of the /r
modifier.
Tags
Feedback
Something wrong with this article? Help us out by opening an issue or pull request on GitHub