Argumentos y valores de retorno

La Lista de Argumentos @_

Los argumentos pasados a una subrutina están disponibles dentro del bloque via el array especial @_.

Retorno de Valores

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.

Ejemplo

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
....

Uso del prefijo &

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);

Omisión de la Lista de Argumentos en la LLamada

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> "; }

Ejercicio 1.15.1   ¿En que contexto se evalúa la llamada al operador diamante en la línea 1 en el programa anterior?

Detectando si un Argumento es de Escritura

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.



Subsecciones
Casiano Rodríguez León
2009-10-04