En los ejemplos vistos hasta ahora, cuando invocamos una subrutina y le pasamos parámetros
en realidad le estamos pasando una lista de datos, que se llama
@_
.
Cuando pasamos arreglos o tablas como parámetros en realidad los estamos vertiendo
elemento por elemento en
@_
,
lo cual parece un poco estúpido a veces, con el
trabajo que nos dio previamente llenarlos. De hecho, si queremos pasar
por ejemplo dos arreglos a la vez, será imposible que la subrutina que los reciba
sepa donde termina uno y empieza el otro, porque lo que está recibiendo es
@_
.
Por esta razón, cuando pasamos varios parámetros y uno de ellos es un arreglo, debemos
poner al arreglo en última posición, para poder identificarlos después en la subrutina.
Lo mismo se aplica a los valores que devuelve una subrutina con
return
.
## forma correcta de pasar más de un parámetro y recibir más de un resultado my ($result1,@result2) = subrutina($arg1,$arg2,@arg3); sub subrutina { my($sarg1,$sarg2,@sarg3) = @_; my ($sresult1,@sresult2); return ($result1,@result2); } ## en cambio, esto no funcionaría my (@result2,$result1) = subrutina($arg1,@arg3,$arg3); # $result1 queda sin asignar sub subrutina { my($sarg1,@sarg3,$sarg3) = @_; # $sarg3 queda sin asignar my ($sresult1,@sresult2); return (@result2,$result1); }
La forma más económica de pasar parámetros a subrutinas es pasarlos como referencias (ver sección
2.3). De esta manera no pasamos los datos en sí, si no la dirección que ocupan en
memoria. Así no es necesario copiar todos los datos a
@_
y la subrutina que reciba las
referencias puede acceder a los datos en su organización original, ya sean escalares, arreglos
o tablas asociativas.
Otra aplicación de las referencias parámetro es que permiten modificar de forma permanente, no local, los datos pasados como argumento. Finalmente, el paso por referencias permite pasar como parámetro otras subrutinas, lo cual puede ser útil en ocasiones.
Veamos un ejemplo:
#!/usr/bin/perl -w # Ejemplo escrito por Bruno Contreras en Julio de 2005 use strict; ## variables del programa principal my ($escalar , @arreglo1 , @arreglo2); ## asignación de valores $escalar = 0; @arreglo1 = (1,2,3); @arreglo2 = (4,5,6); ## llamada a subrutina y conversión de la referencia recibida a un arreglo my @resultado = @{ lee_arreglos( $escalar , \@arreglo1 , \@arreglo2 ) }; print "resultado: $resultado[0] , $resultado[1] , $resultado[2]\n"; ############### subrutinas ################## sub lee_arreglos { # parámetros pasados my ($sarg1,$rarreglo1,$rarreglo2) = @_; # variables locales my @res = ( $sarg1, $rarreglo1->[0], $rarreglo2->[0] ); return \@res; # devuelve una referencia a un arreglo como resultado }