En Perl, los argumentos de la subrutina almacenados en @_
son siempre alias de los valores en el sitio de la llamada. Este alias solo persiste en @_
, si copia valores, eso es lo que obtiene, valores.
lo que en este substitución:
sub example {
# @_ is an alias to the arguments
my ($x, $y, @rest) = @_; # $x $y and @rest contain copies of the values
my $args = \@_; # $args contains a reference to @_ which maintains aliases
}
Tenga en cuenta que este aliasing ocurre después de expansión de la lista, por lo que si usted pasó una matriz para example
, la matriz se expande en el contexto de lista, y @_
se ajusta a los alias de cada elemento de la matriz (pero la matriz en sí no está disponible para example
). Si quisieras lo último, pasarías una referencia a la matriz.
Aliasing de argumentos de subrutina es una característica muy útil, pero se debe utilizar con cuidado. Para evitar la modificación involuntaria de variables externas, en Perl 6 debe especificar que desea argumentos con alias editables con is rw
.
Uno de los trucos menos conocidos pero útil es usar esta característica aliasing para crear refs matriz de alias
my ($x, $y) = (1, 2);
my $alias = sub {\@_}->($x, $y);
$$alias[1]++; # $y is now 3
o rodajas alias:
my $slice = sub {\@_}->(@somearray[3 .. 10]);
También resulta que el uso de sub {\@_}->(LIST)
a crear una matriz a partir de una lista es realmente más rápido que
[ LIST ]
ya que Perl no necesita copiar todos los valores. Por supuesto, la desventaja (o alcista dependiendo de su perspectiva) es que los valores siguen siendo alias, por lo que no puede cambiarlos sin cambiar los originales.
Como tchrist menciona en un comentario a otra respuesta, cuando se utiliza cualquiera de los constructos de solapamiento de Perl en @_
, la $_
que proporcionan usted es también un alias a los argumentos a subrutinas originales. Tales como:
sub trim {s!^\s+!!, s!\s+$!! for @_} # in place trimming of white space
Por último todos este comportamiento es encajable, por lo que cuando se utiliza @_
(o una porción de ella) en la lista de argumentos de otra subrutina, que también recibe los alias a los argumentos de la primera subrutina:
sub add_1 {$_[0] += 1}
sub add_2 {
add_1(@_) for 1 .. 2;
}
Perl no es C. No espere que se comporte como C, o cualquier lenguaje derivado de C como C++ o Java. –
[perldoc perlsub] (http://perldoc.perl.org/perlsub.html) – Ether
Su pregunta es sobre '@ _', no' $ _'. Y '@ _' en un' sub' a menudo contiene alias en lugar de copias de valores. Por lo tanto, si no desea este comportamiento en su 'sub', asegúrese de copiar la entrada de' @ _' a 'mis' variables al inicio. – aschepler