Como han dicho otros, esto está documentado.
Mi entendimiento es que el comportamiento de aliasing @_
, for
, map
y grep
ofrece una velocidad y una optimización de la memoria, así como proporcionar interesantes posibilidades para la creatividad.Lo que sucede es esencialmente una invocación de referencia paso a paso del bloque del constructo. Esto ahorra tiempo y memoria al evitar la copia innecesaria de datos.
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 @_;
}
Nota el uso de List::MoreUtilsapply
función. Funciona como map
pero hace una copia de la variable de tema, en lugar de usar una referencia. Si no te gusta escribir código como:
my @foo = map { my $f = $_; $f =~ s/foo/bar/ } @bar;
te encantará apply
, que la convierte en:
my @foo = apply { s/foo/bar/ } @bar;
Algo a tener en cuenta: si pasa leer sólo los valores en una de estas construcciones que modifica sus valores de entrada, obtendrá un error "Modificación de un valor de solo lectura intentada".
perl -e '$_++ for "o"'
Fwiw, este comportamiento se documenta en la página de manual perlsyn: http://perldoc.perl.org/perlsyn.html#Foreach-Loops – friedo
pensar en él como declarar un iterador. En básicamente cada idioma que implementa iteradores, puede usar el iterador para modificar el valor existente. Si quieres copiar la semántica, solo haz una copia. :) –