En Perl, los subprogramas reciben argumentos a través de una variable especial de matriz @_, donde se colocan automáticamente todos los parámetros enviados. Una característica de Perl es que los parámetros entran en @_ por referencia, lo que significa que modificar los elementos dentro de la función cambia sus valores fuera de ella.
Para evitar cambios inesperados en los datos enviados, se recomienda copiar los parámetros en variables:
sub sum { my ($a, $b) = @_; return $a + $b; }
Las funciones en Perl siempre devuelven una lista de valores, y el resultado de la función es la última lista calculada o un operador return explícito.
sub minmax { my ($x, $y) = @_; return ($x < $y ? $x : $y, $x > $y ? $x : $y); } my ($min, $max) = minmax(4, 7); # $min = 4; $max = 7
Si se llama a la función en un contexto escalar, devuelve la cantidad de elementos devueltos, a menos que el resultado esté encerrado en un escalar.
¿Cómo pasar un gran número de variables a una función Perl sin cambiar accidentalmente los valores de las variables originales?
Se responden inconscientemente: "¡Solo hay que copiar los argumentos en variables como de costumbre!"
Respuesta correcta:
La copia solo funciona para escalares. Si estás trabajando con matrices o hashes, utiliza referencias para gestionar la transmisión de datos de manera explícita y evitar copias por referencia:
sub modify { my ($arr_ref) = @_; push @$arr_ref, 'new'; # modifica la matriz original } my @data = (1, 2, 3); modify(\@data); # ahora @data = (1, 2, 3, 'new')
Historia
Historia 1
En un gran script de procesamiento de informes, una función interna modificaba los valores de los elementos de una matriz enviada desde el programa principal. Como resultado, después de ejecutar la función, los datos originales se corrompieron. El error fue que el autor de la función no hacía copias de los valores de entrada, suponiendo que los cambios serían locales, lo cual es incorrecto para @_ con matrices.
Historia 2
Al migrar scripts de Perl 4 (donde las variables se copiaban de otra manera), el equipo se encontró con un problema: la transmisión de hashes anidados causaba "filtraciones" inesperadas de datos entre llamadas a subprogramas — la modificación de campos del hash en una función afectaba a otras partes del código. La razón era la referencia al hash en la lista @_.
Historia 3
Un desarrollador implementó una función que devolvía una matriz de resultados, pero en el lugar de la llamada utilizó un contexto escalar:
$count = func(@params);. Se esperaba que la variable recibiera el valor del primer elemento devuelto, pero en realidad, en$countterminó el número de elementos en la lista, lo que provocó retrasos en los cálculos y confusiones.