Definición de funciones
La definición de funciones permite asociar un nombre a un conjunto de instrucciones Perl. La sintaxis para la definición de función es:
sub nombre_de_función {
instrucciones;
[return Variable o expresión;]
}
donde nombre_de_función representa el nombre de la función. A cada llamada a la función, el código de instrucciones delimitadas por llaves se ejecuta. La definición de una función es global y en consecuencia puede insertarse al principio o al final del archivo.
La llamada a la función se puede realizar de dos formas:
& nombre_de_función;
do nombre_de_función();
Las dos formas producen el mismo resultado con la excepción de que en el caso de do hay siempre que poner los paréntesis. Una llamada a una función puede insertarse en las estructuras y operadores en Perl.
El valor devuelto por la llamada a una función corresponde al valor precisado por el operador return. Cuando este está ausente, el resultado de la última instrucción corresponde al resultado de la última instrucción ejecutada en el cuerpo de la función. Por ejemplo:
sub diferencia {
if ($x < $y) {
print "$x es inferior a $y\n";
$y-$x;
}
else {
print "$x es superior o igual a $y\n";
$x-$y;
}
}
$x = 2; $y = 3;
$abs = &diferencia; # $abs = 1
En este ejemplo, la función visualiza un mensaje y devuelve el valor absoluto de la diferencia de $x y $y. Permutando las instrucciones de visualización y de cálculo, la función devolverá 1, valor correspondiente a una visualización correcta.
Los argumentos de una función.
Al llamar a una función cuando esta va seguida de una lista de variables, éstas últimas se consideran como sus argumentos. El lenguaje Perl duplica el contenido de estas variables en la variable predefinida @_ durante la ejecución de la función. La variable @_ permite así acceder a los parámetros de la función. Estos se colocan en la matriz $_[0], $_[1], ..., $_[n-1] referenciando los diferentes argumentos de la función. Por ejemplo.
sub diferencia {
if ($_[0] < $_[1]) {
$_[1]-$_[0];
}
else {
$_[0]-$_[1];
}
}
$abs = &diferencia(2,3); # $abs = 1
Las variables locales y globales.
Las variables referenciadas en una función son de modo predeterminado variables globales, es decir, comunes a todo el script. Para evitar los conflictos entre las variables propias de la función y las otras variables, es necesario declarar explícitamente las variables locales (propias de la función) mediante el operador local. Este operador tiene como argumentos una lista de nombres de variables a las que asocia variables locales. Cuando hay conflicto entre nombre de variables locales y globales en la definición de una función, sólo se tiene en cuenta la variable local en el cuerpo de la función y el valor global queda sin cambios. Por ejemplo:
sub producto {
local($p) = 1;
foreach $_(@_) {
$p *= $_;
}
}
$p = 3;
print &producto(2,3,4); # visualiza 24
print "$p\n"; # visualiza 3
Es aconsejable asignar a las variables locales los argumentos pasados a la función. Esto permite una mejor legibilidad de las funciones. Esto se realiza combinando el operador local con la variable predefinida @_. Por ejemplo:
sub Area_cuadrado {
local($radio) = @_;
return $radio*$radio; # el return sobra
}
Paso de parámetros por referencia.
Hasta ahora hemos visto el pasa de parámetros por valor, es decir, no es posible cambiar los valores globales de los argumentos. Para hacer esto posible es necesario pasar a la función no los valores, sino los nombres de estas variables. Este modo se denomina paso por referencia y se implementa prefijando el nombre de la variable con un arterisco *.
En el momento de la definición de una funcioón cuyos argumentos se pasan por referencia, la asignación de los argumentos a las variables locales se hacen mediante el operador local(*nombre). El ejemplo siguiente ilustra este modo de paso de argumentos describiendo la rutina swap que hace la permuta de los valores de los argumentos.
sub swap {
local(*x, *y) = @_; # asignación local de los argumentos
local($t); # variable local
$t = $x;
$x = $y;
$y = $t;
return @_; # resultado de la función
}
$a = 4; $b = 1;
&swap(*a, *b); # $a =1; $b = 4;
Resulta esencial que la asignación de los argumentos a las variables locales se haga mediante el operador local. Ya que la asignación directa de la variable local mediante *nombre=valor modifica las ocurrencias de la variable nombre en el script. Por ejemplo:
sub swap {
(*a, *b) = @_; # asignación de argumentos
local($t);
$t = $a;
$a = $b;
$b = $t;
return @_;
}
$a = 4; $b = 1;
$x = "pi"; $y = 1.414;
&swap(*x, *y); # $x = 1.414; $y = "pi"
print "a=$a, b=$b\n"; # $a = 1.414; $b = "pi"