La matriz de argumento @_
no se comporta de la manera en que cree que lo hace. Los valores en @_
en una subrutina son en realidad aliases for the real arguments:
El array @_ es una matriz local, pero sus elementos son alias para los parámetros escalares reales.
Cuando se dice esto:
sub s {
"huh?" =~ /(.*)/;
print for @_;
}
"ok" =~ /(.*)/;
s("$1", $1);
El $1
en el primer argumento a s
se evalúa inmediatamente por la interpolación de cadenas pero el segundo argumento no se evalúa, es justo señalar que el segundo valor la versión del submarino de @_
es $1
(la variable real $1
, no su valor). Luego, dentro de s
, el valor de $1
se cambia por su expresión regular. Y ahora, su @_
tiene un alias para la cadena "ok"
seguido de un alias para $1
, estos alias se resuelven con el print
en su ciclo.
Si cambia la función a esto:
sub s {
my @a = @_;
"huh?" =~ /(.*)/;
print for @a;
}
o incluso esto:
sub s {
local $1;
"huh?" =~ /(.*)/;
print for @_;
}
Luego le ponen las dos líneas de "ok" que se está esperando. Lo gracioso (curioso, no gracioso, ja, ja) es que esas dos versiones de s
producen el resultado esperado por diferentes razones.La versión my @a = @_;
extrae los valores actuales de los alias en @_
antes de que la expresión regular tenga sus manos en $1
; la local $1;
version localiza la variable $1
a la sub dejando el alias en @_
referencia a la versión de $1
desde fuera del sub:
Un modifica local de las variables que se enumeran a ser local en el bloque que lo contiene, un archivo o eval.
las singularidades de este tipo son eso que siempre debe copiar los valores de las variables de captura de expresiones regulares numeradas a las variables de su tan pronto como sea posible y por qué se desea expandir @_
justo al inicio de sus funciones (a menos que sepa por qué no quieres hacer eso).
Afortunadamente no he abusado demasiado de la terminología, este es uno de esos rincones extraños de Perl del que siempre me he mantenido alejado porque no me gusta hacer malabares con hojas de afeitar.