As others have said, this is documented.
My understanding is that the aliasing behavior of @_
, for
, map
and grep
provides a speed and memory optimization as well as providing interesting possibilities for the creative. What happens is essentially, a pass-by-reference invocation of the construct's block. This saves time and memory by avoiding unnecessary data copying.
use strict;
use warnings;
use List::MoreUtils qw(apply);
my @array = qw( cat dog horse kanagaroo );
foo(@array);
print join "\n", '', 'foo()', @array;
my @mapped = map { s/oo/ee/g } @array;
print join "\n", '', 'map-array', @array;
print join "\n", '', 'map-mapped', @mapped;
my @applied = apply { s/fee//g } @array;
print join "\n", '', 'apply-array', @array;
print join "\n", '', 'apply-applied', @applied;
sub foo {
$_ .= 'foo' for @_;
}
Note the use of List::MoreUtils apply
function. It works like map
but makes a copy of the topic variable, rather than using a reference. If you hate writing code like:
my @foo = map { my $f = $_; $f =~ s/foo/bar/ } @bar;
you'll love apply
, which makes it into:
my @foo = apply { s/foo/bar/ } @bar;
Something to watch out for: if you pass read only values into one of these constructs that modifies its input values, you will get a "Modification of a read-only value attempted" error.
perl -e '$_++ for "o"'