3. Definir una subrutina
Palabra
Nombre de la
reservada sub
subrutina
1.sub marineros {
2. $n += 1; # Global variable $n
3. print "¡Hola marinero $n!n";
4.}
4. Definir una subrutina
La subrutina puede estar en cualquier parte del
fichero.
La definición de subrutinas es global: una vez definidas
se pueden usar desde cualquier parte o fichero
durante la ejecución del script.
Si dos subrutinas tienen el mismo nombre, se aplica la
última que se lee
En este caso se lanza un warning.
Todas las variables definidas hasta ahora son globales.
5. Llamar a una subrutina
1.&marineros
Se llama al nombre de la función con un &
delante
6. Retorno de valores
Todas las funciones en perl deben devolver algo
SIEMPRE
Perl devuelve por defecto el valor de la última
expresión evaluada dentro de la subrutina.
7. Retorno de valores
1.$a = 10;
2.$b = 20;
3.sub funcion1 {
4. say "Dentro de función 1";
5. $a + $b;
6.}
7.
8.say "funcion1: ",&funcion1;
8. Retorno de valores
1.$a = 10;
2.$b = 20;
3.sub funcion2 {
4. say "Dentro de función 2";
5. $a + $b;
6. say "Aquí imprimimos algo";
7.}
8.say "funcion2: ",&funcion2
9. Retorno de valores
1.$a = 10;
2.$b = 20;
3.sub funcion2 {
4. say "Dentro de función 2";
5. $a + $b;
6. say "Aquí imprimimos algo";
7.}
8.say "funcion2: ",&funcion2
-------
funcion2: 1
10. Retorno de valores
Se devuelve el resultado de la última expresión
evaluada.
La última expresión evaluada es print, por lo
que se devuelve el resultado de evaluar print
El 1 significa que el print se evaluó
correctamente.
13. Argumentos
Nuestras subrutinas son muy poco prácticas y
difíciles de mantener: tenemos que definir
constantemente variables globales para poder
usarlas.
14. Argumentos
Nuestras subrutinas son muy poco prácticas y
difíciles de mantener: tenemos que definir
constantemente variables globales para poder
usarlas.
...pero perl permite pasar una LISTA de
argumentos a una función
15. Argumentos
Nuestras subrutinas son muy poco prácticas y
difíciles de mantener: tenemos que definir
constantemente variables globales para poder
usarlas.
...pero perl permite pasar una LISTA de
argumentos a una función
insisto: LISTA de argumentos
16. Argumentos
Así llamamos a una función y le pasamos una
lista de argumentos
1.
$max = &maximo(10, 50);
Perl almacena la lista que recibe como argumento
en el array @_
Reescribamos nuestra función maximo:
17. Argumentos
1.$a = 10;
2.$b = 20;
3.sub maximo {
4. if ($_[0] > $_[1]) {
5. $_[0];
6. } else {
7. $_[1];
8. }
9.}
10.
11.say "maximo: ",&maximo($a, $b)
...un poco complicada de leer. En seguida
veremos como mejorar esto.
18. Argumentos: @_
@_ es una lista privada dentro de la función: si
esta lista tenía un valor antes de la llamada,
este valor se guarda y el intérprete lo recupera
cuando se sale de la subrutina.
Si esto no fuese así, sería complicado anidar
subrutinas.
Incluso en subrutinas recursivas, cada llamada
tiene su propia copia de la lista @_.
19. Variables privadas
Por defecto, perl siempre trabaja con variables
globales.
Perl permite crear variables privadas o “variables
léxicas” (lexical variables) a través del operador my.
1.sub max {
2. my($m, $n); # variables privadas: válidas sólo en este
#bloque de código
3. ($m, $n) = @_; # asignamos valores a las variables
4. if ($m > $n) {
5. $m
6. } else {
7. $n
8. }
9.}
20. Variables privadas
Escribimos una versión más legible de nuestra
función maximo
1.$a = 100;
2.$b = 200;
3.sub maximo {
4. my($a,$b);
5. ($a, $b) = @_;
6. if ($a > $b) { $a; } else { $b; }
7.}
8.
9.say "maximo: ",&maximo(10, 20);
10.say "maximo: ",&maximo($a, $b)
22. Número variable de
argumentos
Las funciones en perl reciben una lista de
argumentos por lo tanto ¿cuántos argumentos
puede recibir una función en perl?
23. Número variable de
argumentos
Las funciones en perl reciben una lista de
argumentos por lo tanto ¿cuántos argumentos
puede recibir una función en perl?
2147483647, es decir, máximo número de
índices que puede tener un array
24. Número variable de
argumentos
Las funciones en perl reciben una lista de
argumentos por lo tanto ¿cuántos argumentos
puede recibir una función en perl?
2147483647, es decir, máximo número de
índices que puede tener un array
Debemos, por tanto, controlar el número de
argumentos que recibimos
25. Argumentos: ejercicios
modificar la función máximo anterior para que
muestre un aviso por pantalla cuando se reciben
más de 2 argumentos.
escribir una función maximo que acepte un
número arbitrario de argumentos
26. Más sobre variables
privadas
Las variables privadas se pueden definir en
cualquier bloque de código:
1. $cuadrado = 10;
2. say "$cuadrado antes vale $cuadrado";
3. foreach (1..10) {
4. my($cuadrado) = $_ * $_;
5. print "$_ al cuadrado es $cuadrado.n";
6. }
7. say "$cuadrado después vale $cuadrado";
1. $cuadrado = 10;
2. say "$cuadrado antes vale $cuadrado";
3. {
4. my($cuadrado) = "C U A D R A D O";
5. print "$cuadrado dentro es $cuadrado.n";
6. }
7. say "$cuadrado después vale $cuadrado";
27. Más sobre variables
privadas
Perl tiende a ser un lenguaje muy permisivo.
Podemos imponer cierta disciplina con el uso del pragma use
strict.
¿Qué hace este pragma? impone restricciones:
nos obliga a declarar todas las variables con my.
más restricciones: perldoc strict.
A partir de la versión 5.12 de perl, se usa strict por defecto, así
que si usamos use 5.012 no tenemos que usar use strict.
Consejo: usar siempre use strict (a no ser que tengáis un buen
motivo para no usarlo... y normalmente no lo tendréis)
29. Devolviendo valores no
escalares
Si se llama a una función en un entorno de
lista, puede devolver una lista de valores
1.sub rango {
2. my ($a,$b) = @_;
3. if ($a > $b) {
4. $b..$a;
5. } else {
6. $a..$b;
7. }
8.}
9.$a = 10;
10.$b = 30;
11.@lista = &rango(10, 30);
30. Devolviendo valores no
escalares
La función wantarray devuelve true en un
contexto de lista y false en un contexto escalar.
31. Devolviendo valores no
escalares
1.sub rango {
La función want array devuelve true en
2. my ($a,$b) = @_; un
3. if (wantarray) {
4. contexto > $b) { y false en un contexto
if ($a de lista escalar.
5. $b..$a;
6. } else {
7. $a..$b;
8. }
9. } else {
10. return abs($a - $b);
11. }
12.}
13.$a = 10;
14.$b = 30;
15.@lista = &rango($a, $b);
16.$escalar = &rango ($a, $b);
17.say "@lista = @lista";
18.say "$escalar = $escalar";
32. state
Si definimos una variable como state dentro de
una subrutina, perl guarda el valor de la misma
entre sucesivas llamadas a una función
(es como una variable static)
Disponible a partir de la versión 5.10 de perl
33. Ejercicios
1. Escribe una subrutina en perl que acepte una lista de números y calcule la suma.
Hacerla de forma que a medida que se llama a la función para sumar números, esta
almacena la suma acumulada en las diferentes llamadas:
acumula (1,2,3) -> 6
acumula (4,5) -> devuelve 6+9=15
2. Modificar la función anterior para resetear el valor acumulado y ponerlo a cero cuando
se le pasa como argumento una lista vacía.
3. Modificar la función anterior para que, al usarse en un entorno escalar, devuelva el
valor acumulado.
Hinweis der Redaktion
\n
- ¿porqué subrutina y no función? para diferenciar las que son nuestreas de las que ya existen en perl, pero se pueden llamar funciones.\n
- ¿porqué subrutina y no función? para diferenciar las que son nuestreas de las que ya existen en perl, pero se pueden llamar funciones.\n
- ¿porqué subrutina y no función? para diferenciar las que son nuestreas de las que ya existen en perl, pero se pueden llamar funciones.\n
- algunos las ponen arriba y otros abajo para que se ve la parte principal del script en primer lugar\n
Ejecutar el script marineros.pl\n
\n
Hacer el ejemplo retorno1.pl\n
¿Qué nos va a salir por pantalla?\n
ejecutar retorno2.pl\n
\n
retorno3.pl\n
\n
\n
\n
Mostrar ahora el ejemplo argumentos1.pl (se muestra en la siguiente transparencia)\n
\n
\n
\n
variables_privadas1.pl\nResaltar que los valores de $a y $b ahora no se cambian, si no hacemos lo del my, sí que se cambian.\n
\n
\n
\n
argumentos_variables1.pl \nargumentos_variables2.pl\n\nMostrar el código de argumentos_variables2.pl y explicarlo. Cosas importantes que contar aquí:\n- uso de variables por defecto\n- uso del shift para vaciar el array de argumentos, muy común\n\n¿Qué ocurre a la función anterior si recibe una lista vacía? -> que devolverá un undef\n
Poner dos ejemplos: variables_privadas2.pl\n $cuadrado = 10;\nsay "\\$cuadrado antes vale $cuadrado";\nforeach (1..10) {\n  my($cuadrado) = $_ * $_;\n  print "$_ al cuadrado es $cuadrado.\\n"; \n}\nsay "\\$cuadrado después vale $cuadrado";\n\nPoner dos ejemplos: variables_privadas3.pl\n$cuadrado = 10;\nsay "\\$cuadrado antes vale $cuadrado";\n{\n  my($cuadrado) = "C U A D R A D O";\n  print "\\$cuadrado dentro es $cuadrado.\\n"; \n}\nsay "\\$cuadrado después vale $cuadrado";\n
¿Qué problema tiene no usar my?\n\npones una variable $error = 20 y 10000 líneas más abajo escribes:\n\nif ($erro > 0) {BLABLABLA}\n\nLa liaste porque el intérprete crea la variable $erro por tí y le signa un certo así que este if siempre será falso.\n\nCon use strict esto da un error.\n
\n
Learning perl 6th ed. Página 76\n\nEjercicio: hacer una función que arregle el problema del rango ( el operador .. sólo funciona cuando el primer operando es menor que el segundo )\ndevolver_array.pl ->\nsub rango {\n    my ($a,$b) = @_;\n    if ($a > $b) {\n        $b..$a;\n    } else {\n        $a..$b;\n    }\n}\n \n$a = 10;\n$b = 30;\n \n@lista = &rango(10, 30);\n \nsay "@lista"\n