Subroutines en PERL

Hasta ahora, todos los «programas» capaces de escribir son bastante ‘lineales’, es decir que se ejecutarían de principio a fin, línea tras línea, sin ningún test o loop, todos en un bloque único.
Es posible de todos modos definir nuestras funciones (o procedimientos, o subroutines o como queráis llamarlas) en perl, y después llamarlas como se llaman las funciones normales del perl.

El modo de definir una función es éste:

sub nombre_de la_función {
contenidos;
de la;
función;
}

Dicha función será llamada como &nombre_de la_función si no se quieren añadir argumentos, &nombre_de la_función ($argumentos, @vanno, %qui) para llamarla con los argumentos.
La «&» es el carácter que identifica las subroutines, del mismo modo en que $ define los escalares.

Las subroutines se pueden definir en cualquier punto del programa, excepto en el interior de otras. [Esto sirve para el perl4, en el 5 puede haber subroutine en otras subroutines, sub (= subroutines) sin nombre, y no es necesario el «&» para llamarlas].

Las sub se pueden utilizar antes de ser definidas.

ex: #!/usr/bin/perl
$bla=3;
&showbla;
$bla=4;
sub showbla {
print «bla è $bla\n»;
}
&showbla

Este ejemplo asigna 3 a $bla, llama la sub, asigna 4 a $bla, después la llama; no importa el lugar en el que está definida.
En la práctica las sub se encuentran al principio del script, rodeadas con la inicialización de las variables que sirven, y después el resto del código. Pero el perl nunca obliga a ser lógicos o claros.

Dentro de una sub, podemos tener acceso a los parámetros pasados (si los hay) a través del especial array @_ . De este modo, el primer valor pasado a la sub será $_[0], el segundo $_[1], etc.

sub printfirstargument {
print $_[0], «\n»;
}

sub printnumberofarguments {
print $#_ +1, «\n»;
}

sub addone {
$_[0] = $[0] +1;
}
$bla = 3;
&addone($bla);

Además, cada función restituye un valor que es la última expresión que se había valorado. Desde una sub se puede regresar a un determinado punto con el comando «return», que volverá al punto asignado como argumento.

sub one {

if ($_[0] == 1) {
controla que el primer argumento sea 1

return «one»;
si es así, restituye la cadena «one»

} else {
si no …

return «not one»;
restituye la cadena «not one»

}
cierra «if/else»

}
cierra la sub

print &one(1), «, «, &one(3), «\n»;
muestra «one, not one»

Veamos ahora un ejemplo más «a mano»: este script leerá los valores en input e imprimirá la media aritmética.

#!/usr/bin/perl
sub media {
local($n, $somma, $media);
foreach $n (@_) {
$somma += $n;
}
$media = $somma/($#_ +1);
return ($media);
}
escribe «Inserta los números:\n»;
@números = <STDIN>;
chop (@números);
$media = &media(@números);
escribe «Media = $media\n»;