You are on page 1of 18

CONTENIDO

Usando Subrutinas ......................................................................................................... 1


Qu es una Subrutina ................................................................................................. 1
Definiendo e invocando una subrutina........................................................................ 1
Forward References a Subrutinas ....................................................................... 4
Retornando un valor desde una Subrutina ................................................................. 4
Valores de Retorno y Expresiones Condicionales............................................... 6
La Sentencia return..................................................................................................... 8
Usando variables locales en Subrutinas ..................................................................... 9
Inicializacin de variables locales ...................................................................... 11
Pasando valores a una Subrutina ............................................................................. 11
Pasando una lista a una Subrutina .................................................................... 13
Llamando Subrutinas desde otras Subrutinas .......................................................... 14
Subrutinas Predefinidas ............................................................................................ 16
Ejemplo de BEGIN .................................................................................... 16
Ejemplo de END ......................................................................................... 16
AUTOLOAD ......................................................................................................... 17
QUE ESTA MAL?...................................................................................................... 18

Usando Subrutinas

Qu es una Subrutina
En Perl, 1 subrutina es una porcin de cdigo separada usada para efectuar una tarea
particular. El programa PERL ejecuta esa porcin de cdigo llamando o invocando la
subrutina.
Una Subrutina se usa para alguno de estos dos propsitos:
Para partir un programa en partes pequeas hacindolo mas fcil de leer y mas
entendible.

Para permitirnos usar una porcin de cdigo para llevar a cabo la misma tarea
varias veces eliminando la duplicacin.

Definiendo e invocando una subrutina.


Listado 9.1 muestra como una subrutina trabaja. Este programa llama una subrutina que
lee una lnea con nmeros desde el standard input file y los separa. El programa luego
efecta su suma.
Listado 9.1. Un programa que usa una subrutina.

1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: &getnumbers;
5: foreach $number (@numbers) {
6: $total += $number;
7: }
8: print ("El total es $total\n");
9:
10: sub getnumbers {

1
11: $line = <STDIN>;
12: $line =~ s/^\s+|\s*\n$//g;
13: @numbers = split(/\s+/, $line);
14: }
SALIDA
$ program9_1
11 8 16 4
El total es 39
$
ANALISIS

Lneas 10-14 son un ejemplo de una subrutina. La palabra reservada (keyword) sub le
dice al Intrprete de Perl que eso es una definicin de una subrutina.

El getnumbers inmediatamente seguido al sub es el nombre de la subrutina; el


programa Perl usa ese nombre cuando invoca la subrutina.
El programa comienza su ejecucin normal empezando por la lnea 3. starts execution in
the normal way, beginning with la lnea 3. La lnea 4 invoca la subrutina getnumbers;
el carcter & le dice al Intrprete de Perl que el siguiente nombre es el nombre de la
subrutina. (Esto asegura que el Intrprete de Perl no confunda nombres de subrutina con
nombres de variables escalares o arreglos)
El Intrprete de Perl ejecuta la lnea 4 bifurcando a la primera sentencia ejecutable
dentro de la subrutina, la cual es la lnea 11. El intrprete entonces ejecuta las Lneas
11-13.

Las Lneas 11-13 crean el arreglo @numbers de la siguiente manera:


La lnea 11 lee una lnea de input desde el standard input file.

La lnea 12 remueve los espacios iniciales y finales (includo el newline) desde


la lnea de input.

La lnea 13 parte la lnea de input en nmeros y asigna el resultado a


@numbers.

Antes de que la lnea 13 finalice, el Intrprete de Perl vuelve al main program y ejecuta
la lnea inmediatamente siguiente a la llamada de la subrutina, la cual es la lnea 5.

Las Lneas 5-7 suman los nmeros usando la sentencia foreach para loopear la lista de
nmeros almacenada en @numbers. (Ojo, el programa no chequea si son nmeros, si
fueran otra cosa los convierte a cero)
La sintaxis para la definicin de una subrutina es:
sub subname {
statement_block
}
subname es el nombre de la subrutina. Como todos los nombres en Perl, subname
consiste en un carcter alfabtico seguido de una o ms letras, dgitos o guiones (_). Es
aconsejable evitar nombres iguales al de una palabra reservada de perl, y no poner todo
el nombre con letras maysculas ya que as es como Perl llama a sus subrutinas internas.

2
statement_block es el cuerpo de la subrutina y consiste en una o mas sentencias Perl.
Cualquier sentencia que puede aparecer en un main program, puede aparecer en una
subrutina.
NOTA
El Intrprete de Perl nunca confunde un nombre de subrutina con el nombre de
una variable escalar o cualquier otro porque puede deducir del contexto cual
nombre estamos haciendo referencia. Pro lo tanto podemos tener una subrutina
y una variable escalar con el mismo nombre. Por ejemplo:
$word = 0;
&word;
Aqu, cuando el Intrprete de Perl ve el & en la segunda sentencia, asume que
esta llamando una subrutina llamada word.
Atencin
Cuando se definen nombres de subrutinas, es conveniente no usar nombres
iguales a las funciones de librera de Perl para evitar errores involuntarios. Si
bien nosotros podemos definir una subrutina llamada split y el Intrprete de
Perl puede distinguir la invocacin de la subrutina split de la funcin de
librera split, (porque el nombre de la subrutina est precedido por un &
cuando se invoca), es muy fcil olvidar tipear el & y caer en el error.
@words = &split(1, 2); # subrutina
@words = split(/\s+/, $line); # library function

Las subrutinas pueden aparecer en cualquier parte de un programa.


Listado 9.2. Un programa conteniendo una subrutina en el medio del main
program.
1: #!/usr/local/bin/perl
2:
3: while (1) {
4: &readaline;
5: last if ($line eq "");
6: sub readaline {
7: $line = <STDIN>;
8: }
9: print ($line);
10: }
11: print ("FIN\n");
SALIDA
$ program9_2
Aqu esta la linea de input
Aqu esta la linea de input
^D
FIN
$
ANALISIS
Este programa lee lineas del std input file y las escribe en el standard output file.

La lnea 4 llama la subrutina readaline. Cuando examina la subrutina, la encuentra


contenida entre las lineas 6 y 8. Ah vemos que lee una lnea y la asigna a la variable
escalar $line.

3
Cuando readaline termina, la ejecucin del programa contina en la lnea 5. Cuando la
lnea 5 es ejecutada, el programa saltea las sentencias correspondientes a la definicin
de la subrutina y contina en la lnea 9. El cdigo dentro de una subrutina nunca es
ejecutado directamente.
TIP
Si bien las subrutinas pueden aparecer en cualquier parte de un programa, es usual
definirlas al principio o al final de un programa. Esto lo hace mas legible.

FORWARD REFERENCES A SUBRUTINAS


Como vimos, el Intrprete de Perl usa el carcter & para indicar que viene una
subrutina.
En Perl 5 no es ne4cesrio el & antes del nombre en la invocacin si la subrutina ya fue
definida. Ejemplo:
sub readaline {
$line = <STDIN>;
}
...
readaline;

Esto es porque el intrprete ya sabe que readaline es una subrutina.


Si escribimos todas las subrutinas hacia el final de un programa, entonces si debemos
preceder su invocacin con el carcter & salvo que hagamos al principio una forward
reference de la misma:
sub readaline; # forward reference
...
readaline;
...
sub readaline {
$line = <STDIN>;
}
El forward reference le dice al Intrprete de Perl que readaline es el nombre de una
subrutina. De esta manera no necesitamos adicionarle el & en la invocacin.
Atencin
Algunas veces si invocamos una subrutina sin el & no obtenemos el resultado
esperado, en estos casos aconsejamos usarlo.

Retornando un valor desde una Subrutina


Veamos nuevamente la subrutina getnumbers del Listado 9.1.
10: sub getnumbers {
11: $line = <STDIN>;
12: $line =~ s/^\s+|\s*\n$//g;
13: @numbers = split(/\s+/, $line);
14: }

4
Si bien esta subrutina es util, tiene una seria limitacin: sobreescribe el arreglo
@numbers (tambien sobrescribe $line). Esto puede traer problemas Por ejemplo, si
consideramos lo siguiente:
@numbers = ("the", "a", "an");
&getnumbers;
print ("El valor de \@numbers es: @numbers\n");

Cuando la subrutina getnumbers es invocada, el valor de @numbers es sobreescrito.


Esto no resulta obvio cuando miramos el programa de arriba.
En torno a esto, podemos usar una propiedad de las subrutinas en Perl: el valor de la
ltima expresin evaluada por la subrutina es considerada automticamente como el
valor de retorno (return value) de la subrutina. Por ejemplo, en la subrutina getnumbers
del Listado 9.1, la ltima expresin evaluada es:
@numbers = split(/\s+/, $temp);
El valor de esta expresin es la lista de nmeros obtenida del splitting de la lnea de
input. De esta manera, la lista de nmeros es el valor de retorno de la subrutina.
Para ver como usar el valor de retorno de una subrutina, veamos el Listado 9.3, el cual
modifica las lneas 4 y 13 del listado 9.1 original para usar el valor de retorno de la
subrutina getnumbers.
Listado 9.3. Un programa que usa en una subrutina el return value.

1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: @numbers = &getnumbers; # as getnumbers retornar su valor en @numbers
5: foreach $number (@numbers) {
6: $total += $number;
7: }
8: print ("El total es $total\n");
9:
10: sub getnumbers {
11: $line = <STDIN>;
12: $line =~ s/^\s+|\s*\n$//g;
13: split(/\s+/, $line); # Este es el return value
14: }
SALIDA
$ program9_3
11 8 16 4
El total es 39
$
ANALISIS
La lnea 4, nuevamente llama a la subrutina getnumbers, pero esta vez, el arreglo
@numbers es asignado a la lista de nmeros ledos desde el standard input file; de esta
manera la asignacin se hace en el cuerpo principal del programa, no en la subrutina,
esto lo hace mas fcil de seguir.

La otra diferencia est en la llamada a la funcin split de la lnea 13. Ahora no se


asigna su resultado a @numbers. De hecho no se le asigna a nada, porque no es necesario
hacerlo.

5
La lnea 13 es la ltima expresin evaluada en getnumbers, por eso automticamente se
convierte en el valor de retorno de la subrutina.

De esta manera cuando en la lnea 4 se llama a la subrutina getnumbers, el listado


retornado por el split es asignado a @numbers.
NOTA
Si la idea de la ltima expresin evaluada es confusa para Uds. No hay nada
malo en crear una variable dentro de la subrutina solo para contener el valor de
retorno. Por ejemplo:
sub getnumbers {
$line = <STDIN>;
$line =~ s/^\s+|\s*\n$//g;
@retval = split(/\s+/, $temp); # the return value
}
Aqu es obvio que el valor de retorno est contenido en @retval.
La desventaja est solo en usar una asignacin cuando no es necesaria.
Eliminarla hace la subrutina mas eficiente. Usar una variable especial para
retornar valores elimina unos cuantos errores que veremos mas adelante.

Se puede usar el valor de retorno de una subrutina en cualquier parte de una expresin.
Por ejemplo:
foreach $number (&getnumbers) {
print ("$number\n");
}
Este foreach itera sobre la lista de nmeros retornados por getnumbers. Cada
elemento de la lista es asignado a $number por turno, lo que produce la impresin de
todos los nmeros de la lista.

VALORES DE RETORNO Y EXPRESIONES CONDICIONALES


Como el valor de retorno de una subrutina es siempre la ltima expresin evaluada, a
veces el valor de retorno no devuelve lo que esperamos.
Listado 9.5: Consideremos nuevamente el ejemplo del Listado 9.1, pero esta vez todo el
trabajo hecho dentro de una subrutina llamada get_total: se leen lneas del Standard
input file, luego se separa en nmeros y los suma.
Listado 9.5. Un programa que ilustra un potencial problema con los valores de
retorno desde las subrutinas.

1: #!/usr/local/bin/perl
2:
3: $total = &get_total;
4: print("El total es $total\n");
5:
6: sub get_total {
7: $value = 0;
8: $inputline = <STDIN>;
9: $inputline =~ s/^\s+|\s*\n$//g;
10: @subwords = split(/\s+/, $inputline);
11: $index = 0;
12: while ($subwords[$index] ne "") {
13: $value += $subwords[$index++];
14: }
15: }

6
SALIDA
$ program9_5
11 8 16 4
El total es
$

ANALISIS
Obviamente que el propsito de Este programa es asignar el contenido de la variable
escalar $value a la variable escalar $total. Pero cuando la la lnea 4 trata de imprimir
el total, el valor de $total est vaco. Que sucedi?

El problema en la subrutina get_total es que la ltima expresin evaluada no es la que


nosotros esperbamos sino la expresin condicional de la Lnea 12.
$subwords[$index] ne ""
El loop de las Lneas 12-14 itera hasta que el valor de la expresin es 0. Cuando el valor
de la expresin es cero, el loop termina, y la subrutina tambin. Por lo tanto el 0 es lo
que retorna y como en un print el 0 se interpreta como string nulo, la lnea 4 imprime lo
siguiente (lo cual no es lo que esperbamos)
El total es
Listado 9.6 muestra como solucionar este problema
Listado 9.6. Un programa que corrige el problema del 9.5

1: #!/usr/local/bin/perl
2:
3: $total = &get_total;
4: print("El total es $total.\n");
5:
6: sub get_total {
7: $value = 0;
8: $inputline = <STDIN>;
9: $inputline =~ s/^\s+|\s*\n$//g;
10: @subwords = split(/\s+/, $inputline);
11: $index = 0;
12: while ($subwords[$index] ne "") {
13: $value += $subwords[$index++];
14: }
15: $retval = $value;
16: }

SALIDA
$ program9_6
11 8 16 4
El total es 39.
$

ANALISIS
Este programa es igual al 9.5 excepto por el agregado de la lnea 15: Esta lnea asigna
el total almacenado en $value a la variable escalar $retval.

7
La lnea 15 asegura que el valor de la ltima expresion evaluada en la subrutina
get_total contenga el total buscado. Luego la lnea 3 efecta una nueva asignacin e
imprime.
Pero en realidad no sera necesario efectuar la asignacin a retval, la subrutina
get_total podra quedar como sigue y seguir siendo efectiva:
sub get_total {
$value = 0;
$inputline = <STDIN>;
$inputline =~ s/^\s+|\s*\n$//g;
@subwords = split(/\s+/, $inputline);
$index = 0;
while ($subwords[$index] ne "") {
$value += $subwords[$index++];
}
$value;
}
Aqu la ltima expresin evaluada es simplemente $value. El valor de esta expresin es
el valor corriente almacenado en $value, es decir la suma de los nmeros de la lnea.
TIP
Las subrutinas que dan su valor de retorno al final (como get_total en Listado
9.6) son conocidas como single-exit modules. Estas subrutinas salvan problemas
como los vistos en Listado 9.5, y normalmente son mucho ms fciles de leer. Por
estas razones es una muy buena idea definirlas as.

La Sentencia return
Otra manera de asegurar el valor de retorno de una subrutina es usando la sentencia
return . La sintaxis es la siguiente:
return (retval);
retval es el valor que queremos retornar. Puede ser un valor escalar (incluido el
resultado de una expresin) o una lista.
Listado 9.7 da un ejemplo de su uso
Listado 9.7. Un programa que usa la sentencia return

1: #!/usr/local/bin/perl
2:
3: $total = &get_total;
4: if ($total eq "error") {
5: print ("No se ingres nada.\n");
6: } else {
7: print("el total es $total.\n");
8: }
9:
10: sub get_total {
11: $value = 0;
12: $inputline = <STDIN>;
13: $inputline =~ s/^\s+|\s*\n$//g;
14: if ($inputline eq "") {
15: return ("error");
16: }
17: @subwords = split(/\s+/, $inputline);
18: $index = 0;

8
19: while ($subwords[$index] ne "") {
20: $value += $subwords[$index++];
21: }
22: $retval = $value;
23: }
SALIDA
$ program9_7
^D
No se ingres nada.
$

ANALISIS
Este programa es similar al Listado 9.6. La nica diferencia de este programa es que
chequea si la lnea de input existe.
Si la lnea de input no existe, la expresin condicional en la lnea 14 es verdadera, y la
lnea 15 es ejecutada. La lnea 15 sale de la subrutina con return value error; Luego
error se asigna a $total en la lnea 3.

Este programa muestra tambin como es til permitir almacenar en variables escalares
nmeros o character strings. Cuando la subrutina get_total detecta el error, asigna un
valor no numrico a $total, lo que permite fcilmente determinar que algo anduvo
mal. En otros lenguajes, no se ofrece esta flexibilidad.
Usando variables locales en Subrutinas
La subrutina get_total en Listado 9.7 define algunas variables que solo se usan dentro
de la subrutina: El arreglo @subwords, y 4 variables escalares $inputline, $value,
$index, y $retval.

Si tenemos la certeza que estas variables solo sern usadas dentro de la subrutina,
podemos decirle a Perl que defina estas variables como locales (local variables).
En Perl 5, existen dos sentencias para definir local variables:
La sentencia my, la cual define variables que solo van a existir dentro de la
subrutina.

La sentencia local, la cual define variables que solo van a existir dentro de la
subrutina y cualquier otra subrutina llamada por esta (como hacer esto lo
veremos luego).

Listado 9.8 muestra como podemos usar my para definir variables que existan solo en la
subrutina.
Listado 9.8. Un programa que usa local variables.

1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: while (1) {
5: $linetotal = &get_total;
6: last if ($linetotal eq "done");
7: print ("Total para esta lnea: $linetotal\n");
8: $total += $linetotal;

9
9: }
10: print ("Total para todas las Lneas: $total\n");
11:
12: sub get_total {
13: my ($total, $inputline, @subwords);
14: my ($index, $retval);
15: $total = 0;
16: $inputline = <STDIN>;
17: if ($inputline eq "") {
18: return ("done");
19: }
20: $inputline =~ s/^\s+|\s*\n$//g;
21: @subwords = split(/\s+/, $inputline);
22: $index = 0;
23: while ($subwords[$index] ne "") {
24: $total += $subwords[$index++];
25: }
26: $retval = $total;
27: }
SALIDA
$ program9_8
11 8 16 4
Total para esta lnea: 39
7 20 6 1
Total para esta lnea: 34
^D
Total para todas las Lneas: 73
$

ANALISIS

Este programa usa dos copias de la variable escalar $total. Una copia de $total esta
definida en el main program y almacena el total de todas las Lneas.

La variable escalar $total est tambin definida en la subrutina get_total; en esta


subrutina, $total referencia al total para una linea en particular, y la lnea 13 define
que sta es una local variable. Como esta variable $total esta definida en la subrutina,
la copia de $total definida en el main program no se ve afectada por la lnea 15 o 24.
Atencin
Como la variable local no es conocida fuera de la subrutina, se destruye cuando
la subrutina es completada. Si la subrutina es llamada nuevamente una nueva
copia de la variable local es definida. El siguiente ejemplo muestra como NO
funcionan:
sub subrutina_count {
my($number_of_calls);
$number_of_calls += 1;
}
Esta subrutina no devuelve el numero de veces que la subrutina es llamada, ya
que cada vez que se la invoca, una nueva copia de $number_of_calls es
definida. Siempre devuelve 1.

Las variables locales pueden aparecer en cualquier parte de un programa, pero para dar
claridad en el cdigo, es preferible ubicarlas al principio.

10
INICIALIZACIN DE VARIABLES LOCALES
Las variables locales pueden ser inicializadas. Ejemplo:

sub my_sub {
my($scalar) = 43;
my(@array) = ("here's", "a", "list");
# code goes here
}
Aqui la variable local $scalar toma un valor inicial de 43, y el arreglo @array es
inicializado con la lista ("here's", "a", "list").
Pasando valores a una Subrutina
Podemos hacer mas flexibles nuestras subrutinas si permitimos que ellas acepten
valores pasados desde el main program. Estos valores se los llama Argumentos.
Listado 9.9 provee un simple ejemplo de una subrutina que acepta tres argumentos
Listado 9.9. Un programa que usa una subrutina to print three numbers and their
total.
1: #!/usr/local/bin/perl
2:
3: print ("Ingrese 3 numeros, uno por vez:\n");
4: $number1 = <STDIN>;
5: chop ($number1);
6: $number2 = <STDIN>;
7: chop ($number2);
8: $number3 = <STDIN>;
9: chop ($number3);
10: &printnum ($number1, $number2, $number3);
11:
12: sub printnum {
13: my($number1, $number2, $number3) = @_;
14: my($total);
15: print ("Los numeros ingresados son: ");
16: print ("$number1 $number2 $number3\n");
17: $total = $number1 + $number2 + $number3;
18: print ("El total es: $total\n");
19: }
SALIDA
$ program9_9
Ingrese 3 numeros, uno por vez:
5
11
4
Los numeros ingresados son: 5 11 4
El total es: 20
$

ANALISIS

La lnea 10 llama a la subrutina printnum. Tres argumentos son pasados a printnum,


los valores almacenados en: $number1, $number2, y $number3. Notar que estos
argumentos son pasados a la subrutina en la misma forma que se pasan a las built-in
library functions.

11
La lnea 13 define copias locales de las variables escalares $number1, $number2, y
$number3 al mismo tiempo que asigna el contenido de la variable de sistema @_.

@_ es creada cada vez que una subrutina es llamada con argumentos. Contiene una lista
con los argumentos en el orden en el cual fueron pasados. En este caso, @_ contiene la
lista (5, 11, 4).

La asignacin de la lnea 13 trabaja igual que siempre: el primer elemento de la lista, 5,


es asignado a la primera variable, $number1; el segundo, 11, es asignado a $number2; y
finalmente, 4, es asignado a $number3.
NOTA
Despus que la variable @_ es creada, puede ser usada dentro de la subrutina
como cualquier arreglo. La siguiente subrutina es equivalente a las Lneas 12-19
de Listado 9.9:
sub printnum {
my($total);
print ("The numbers you entered: ");
print ("$_[0] $_[1] $_[2]\n");
$total = $_[0] + $_[1] + $_[2];
print ("The total: $total\n");
}
Aqu, $_[0] referencia al primer elemento del arreglo @_, $_[1] referencia al
Segundo elemento, y $_[2] referencia al tercero.
Esta subrutina es mas eficiente, pero mas difcil de escribir y leer.
TIP
Usualmente es mejor definir variables locales y asignar @_ a ellas para que as
sea mas fcil de entender el cdigo.

Listado 9.10 es otro ejemplo de un programa que pasa argumentos a una subrutina. Este
programa usa la misma subrutina para contar el numero de palabras y el numero de
caracteres que recibe por STDIN.
Listado 9.10. Otro ejemplo de una subrutina con argumentos pasados.

1: #!/usr/local/bin/perl
2:
3: $wordcount = $charcount = 0;
4: $charpattern = "";
5: $wordpattern = "\\s+";
6: while ($line = <STDIN>) {
7: $charcount += &count($line, $charpattern);
8: $line =~ s/^\s+|\s+$//g;
9: $wordcount += &count($line, $wordpattern);
10: }
11: print ("Total: $wordcount palabras, $charcount caracteres\n");
12:
13: sub count {
14: my ($line, $pattern) = @_;
15: my ($count);
16: if ($pattern eq "") {
17: @items = split (//, $line);
18: } else {
19: @items = split (/$pattern/, $line);
20: }
21: $count = @items;
22: }

12
SALIDA

$ program9_10
Esta es la lnea de input.
Aqui hay otra linea.
^D
Total: 10 palabras, 46 caracteres
$

PASANDO UNA LISTA A UNA SUBRUTINA


Si queremos pasar una lista a una subrutina veamos el siguiente ejemplo:
La siguiente subrutina suma los elementos de una lista e imprime el resultado

sub addlist {
my (@list) = @_;
$total = 0;
foreach $item (@list) {
$total += $item;
}
print ("The total is $total\n");
}

Invocaciones ejemplo:

&addlist (@mylist);
&addlist ("14", "6", "11");
&addlist ($value1, @sublist, $value2);

En cada caso, los valores son juntados en una sola lista, y pasados como una lista simple
a addlist.
Como los valores son juntados, entonces solo se debe incluir una lista en los argumentos
de una sub y es conveniente ponerla COMO ULTIMO ARGUMENTO

La subrutina:

sub twolists {
my (@list1, @list2) = @_;
}

No es til porque las dos listas se juntan y SIEMPRE la se asigna la lista vaca a
@list2, ya que @list1 absorbe TODO el contenido de @_.

Otro Ejemplo:

sub twoargs {
my ($scalar, @list) = @_;
}

Invocacin:
&twoargs(47, @mylist);

13
EL VALOR 47 es asignado a $scalar, y @mylist es asignado a @list.

Si queremos podemos invocar a twoargs con una lista simple como sigue:
&twoargs(@mylist);
Con el mismo resultado que antes, el primer elemento de la lista se asigna a $scalar, y
el resto a @list.
Llamando Subrutinas desde otras Subrutinas
En Perl, podemos llamar subrutinas desde otra subrutina. Para hacerlo, se usa la misma
sintaxis que vinimos empleando.
Las Subrutinas que son llamadas desde otras subrutinas se las conoce como nested
subrutinas
Listado 9.11. Ejemplo de nested

1: #!/usr/local/bin/perl
2:
3: ($wordcount, $charcount) = &getcounts(3);
4: print ("Totals for three lines: ");
5: print ("$wordcount words, $charcount characters\n");
6:
7: sub getcounts {
8: my ($numLines) = @_;
9: my ($charpattern, $wordpattern);
10: my ($charcount, $wordcount);
11: my ($line, $linecount);
12: my (@retval);
13: $charpattern = "";
14: $wordpattern = "\\s+";
15: $linecount = $charcount = $wordcount = 0;
16: while (1) {
17: $line = <STDIN>;
18: last if ($line eq "");
19: $linecount++;
20: $charcount += &count($line, $charpattern);
21: $line =~ s/^\s+|\s+$//g;
22: $wordcount += &count($line, $wordpattern);
23: last if ($linecount == $numLines);
24: };
25: @retval = ($wordcount, $charcount);
26: }
27:
28: sub count {
29: my ($line, $pattern) = @_;
30: my ($count);
31: if ($pattern eq "") {
32: @items = split (//, $line);
33: } else {
34: @items = split (/$pattern/, $line);
35: }
36: $count = @items;
37: }
SALIDA
$ program9_11
This is a line of input.
Here is another line.

14
Here is the last line.
Totals for three Lines: 15 words, 70 characters

15
Subrutinas Predefinidas
Perl considera las subrutinas cuyo nombre est todo en maysculas como parte del
ncleo, y son llamadas automticamente por el sistema
BEGIN subrutina, se llama ANTES que cualquier sentencia. Es ms, se ejecuta
ANTES que los script regulares sean analizados.

END subrutina, se llama ANTES que termine el script regular, al mismo tiempo
que sale del intrprete de perl

AUTOLOAD subrutina, se carga si hacemos una llamada a una subrutina


inexistente. La variable $AUTOLOAD contiene el nombre de la sub que dio
error, la variable @_ contiene la informacin pasada en la rutina que dio error.

Ejemplo de BEGIN

BEGIN {

print("Hi! Welcome to Perl!\n");

Cuando comienza la ejecucin del script aparece:

Hi! Welcome to Perl!

Ejemplo de END

END {

print("Thank you for using Perl!\n");

El cdigo de la subrutina END SIEMPRE se ejecuta, salvo an si el programa termina


con die. Por ejemplo:

die("Prepare to die!\n");

END {

print("Ha! You can't kill me!\n");

Salida:

Prepare to die!

Ha! You can't kill me!

16
NOTA
Se pueden definer varias subrutinas END, en ese caso, se ejecutan
en el orden inverso de apariencia (la ultima se ejecuta primero)

AUTOLOAD

Se carga si hacemos una llamada a una subrutina inexistente. La variable


$AUTOLOAD contiene el nombre de la sub que dio error, la variable @_ contiene la
informacin pasada en la rutina que dio error. Ejemplo:
Listado 9.15. Un programa que usa AUTOLOAD.

1: #!/usr/local/bin/perl

2:

3: &nothere("hi", 46);

4:

5: AUTOLOAD {

6: print("subrutina $AUTOLOAD not found\n");

7: print("arguments passed: @_\n");

8: }

SALIDA

$ program9_15

subrutina main::nothere not found

arguments passed: hi 46

TIP
AUTOLOAD es til para organizar el Programa Perl en mdulos

17
QUE ESTA MAL?
1. #!/usr/local/bin/perl

for ($count = 1; $count <= 10; $count++) {


&print_ten ($count);
}
sub print_ten {
local ($multiplier) = @_;
for ($count = 1; $count <= 10; $count++) {
$printval = $multiplier * 10 + $count;
print ("$printval\n");
}
}

2. #!/usr/local/bin/perl

$line = <STDIN>;
@words = split(/\s+/, $line);
$searchword = <STDIN>;
&search_for_word (@words, $searchword);
sub search_for_word {
local (@searchlist, $searchword) = @_;
foreach $word (@searchlist) {
return (1) if ($word eq $searchword);
}
$retval = 0;
}

3. #!/usr/local/bin/perl

$line = <STDIN>;
@words = &split_la lnea($line);
print ("@words\n");
sub split_la lnea {
local ($line) = @_;
local (@words);
@words = split(/\s+/, $line);
if (@words == 0) {
@words = ("empty list");
}
}

18

You might also like