Los argumentos pasados a una subrutina están disponibles
dentro del bloque via el array
especial @_
.
El valor retornado puede hacerse explícito utilizando
el operador return <expresion>
el cual termina la subrutina.
Si no se usa, el valor retornado por la subrutina es el valor de la
última expresión computada.
Veamos un ejemplo (el hash %ENV
contiene las variables de entorno
de la ejecución del programa):
lhp@nereida:~/Lperl/src$ cat -n return.pl 1 #!/usr/bin/perl -w 2 use strict; 3 use List::Util qw(max); 4 5 sub dictionary_order { 6 my @ordered = sort @_; 7 return @ordered; 8 } 9 10 sub maxlength { 11 max map { length } @_; 12 } 13 14 # Formatted print of a hash 15 sub fprinth { 16 my %h = @_; 17 18 my @a = &dictionary_order(keys %h); 19 my $max = maxlength(@a); 20 printf("%-${max}s => %s\n",$_,$h{$_}) for @a; 21 } 22 23 # main 24 fprinth(%ENV);
El formato %-${max}s
hace que el argumento se alinee a izquierda
y se expanda con blancos hasta max
espacios.
Observe como los argumentos en la llamada se han puesto entre paréntesis. Al ejecutar el programa anterior obtenemos una salida similar a esta:
lhp@nereida:~/Lperl/src$ return.pl CVSROOT => /var/cvs HOME => /home/lhp LANG => es_US.UTF-8 LANGUAGE => es_ES:es:en_GB:en LESSCLOSE => /usr/bin/lesspipe %s %s ....
Al igual que las variables, las subrutinas tiene un símbolo de prefijo que indica que se trata de funciones.
El nombre ''formal'' de una subrutina tiene el prefijo &
, el cual puede usarse en la llamada:
@sorted = &dictionary_order("eat", "at", "Joes");
sin embargo, no debe usarse cuando se define la subrutina.
El prefijo &
puede omitirse si por el contexto es claro que se trata de una
llamada a función:
@sorted = dictionary_order ("eat", "at", "Joes"); @sorted = dictionary_order (@unsorted); @sorted = dictionary_order (@sheep, @goats, "shepherd", $goathered);
Si una subrutina no requiere argumentos, puede ser llamada con una lista vacía de argumentos. La lista puede ser completamente omitida siempre que Perl conozca de antemano que se trata de una función. Asi tenemos:
lhp@nereida:~/Lperl/src$ cat -n get_next.pl 1 sub get_next { return <>; } 2 3 prompt(); # correcto 4 $next = get_next(); #correcto 5 print $next; 6 7 prompt; # error; prompt no ha sido definido aún 8 ($next) = get_next; # correcto: get_next fue definido arriba 9 print $next; 10 sub prompt { print "next> "; }
La función readonly en Scalar::Util permite determinar si un argumento es una variable o un valor:
lhp@nereida:~/Lperl/src/testing$ cat -n readonly.pl 1 use warnings; 2 use strict; 3 use Carp; 4 use Scalar::Util qw(readonly); 5 6 sub ro { 7 print "readonly($_[0])=".readonly($_[0])."\n"; 8 $_[0] = 'xxx'; 9 } 10 11 my $x = 4; 12 13 eval { ro($x) } or print $@; 14 eval { ro(-8) } or print $@; 15 eval { ro('lonely') } or print $@;Cuando se ejecuta, el programa anterior produce una salida como:
lhp@nereida:~/Lperl/src/testing$ perl readonly.pl readonly(4)=0 readonly(-8)=8388608 Modification of a read-only value attempted at readonly.pl line 8. readonly(lonely)=8388608 Modification of a read-only value attempted at readonly.pl line 8.