#!/usr/bin/perl
# En Perl siempre hay que poner las {}
for ($i = 0; $i < 10; $i++)
{$a[$i] = $i + 10;
}# Podemos usar el operador rango
for $i (0..10) {
$a[$i] = $i + 10;
}$i = 0;
while ($i < 10)
{print "$i -> $a[$i]\n";
#$i++; #En este caso puede sustituir al bloque continue
}continue
{$i++;
}
print "-------------------------------\n";
while ($i > 0)
L0:
{$i--;
print "$i -> $a[$i]";
if ($i > 4)
{print "\n";
#next;
next L0; #Etiquetas utiles con bucles animados
}print " **\n";
last if ($i == 1);
}
print "-------------------------------\n";
foreach $i (@a)
{print "$i ";
}print $i++ while ($i < 10);
print "\n";
Perl es quizás el lenguaje que nos ofrece más posibilidades para
implementar bucles. Ofrecer bucles for
, while
y do .. while
con idéntico formato a C.
Los bucles for
y while
son equivalente
siendo for
una versión compacta de los bucles
while
. Ambos repetirán las expresiones en el bloque de
código que sigue mientras se cumpla una cierta condición. Si bien, el
concepto es el mismo, los bucles for
se suelen utilizar en
combinación con un contador mientras que los bucles while
se suelen utilizar en casos más generales, simplemente por conveniencia.
Los bucles for
siguen la siguiente sintaxis:
for ( inicializacion(); condicion(); repeticion())
{
instrucciones }
inicializacion
se ejecuta solo una vez antes de empezar
el bucle. A continuación se comprueba si se cumple
condicion
, de lo contrario el bucle pararía. Por cada
iteración del bucle, antes de re-evaluar la condición
repeticion
se ejecuta.
SABÍAS QUE?
Al igual que sucede con C, cada uno de los bloques de
for
puede ser tan complejo como queramos, pudiendo escribir código como el siguiente:for ($i = 0; $i < 10; $a[$i++] = $i + 10) {}; for ($i = 0; $i < 10; print $a[$i++] ." ") {};
Nótese que, puesto que las llaves son obligatorias, debemos incluirlas al final de nuestro bucle
for
, incluso si no necesitamos ejecutar ninguna instrucción adicional.
Sabiendo todo esto, cualquier bucle for
se puede
escribir de la siguiente forma:
inicializacion ();while (condicion()) {
instrucciones;
repeticion(); }
A diferencia de C, Perl obligata siempre a encerrar el bloque de instrucciones del bucle entre llaves.
Nota: El código de arriba no muestra el bucle do… while ya que no aporta ninguna información extra. Solo tienes que tener en cuenta que el bucle se repite HASTA que se cumpla la condición, y no MIENTRAS
Los bucles for
pueden iterar arrays y listas de forma
automática, así que podemos escribir nuestros bucles for
usando el operador de rango de la siguiente forma:
for $i (0..9) {
$a[$i] = $i + 10;
}
SOY NOVATO
En este ejemplo, puesto que como estamos transformando una lista (generada por el buclefor
) en otra lista, podríamos utilizarmap
@a = map {$_ + 10} 0 .. 9;
Como sucede con if
, en Perl for
admite una
forma reducida cuando solo necesitamos ejecutar una instrucción. Esta
forma se llama postfija (postfix) y nos permite escribir el
código de inicialización de nuestro array de la siguiente forma.
$a[$_] = $_ + 10 for 0 .. 9;
Como podéis ver el bucle for
va al final y no estamos
utilizando ninguna variable, por lo que la variable por defecto
$_
toma los valores del bucle.
Además Perl ofrece un constructor foreach
que es
funcionalmente equivalente a for
y un constructor
until
como complemento a while
(de la misma
forma que unless
complementa if
).
SABÍAS QUE
Perl nos permite generar matrices a partir del contenido de un determinado directorio y patrón. Esto se conoce como globbing y nos permite listar ficheros de forma muy sencilla como primer paso en scripts más complicados
foreach $f (</tmp/*[yb]>) { print "--> $f\n";}
La línea anterior lista todos los ficheros terminados en
y
yb
en el directorio/tmp
.
Pero además de todo esto, Perl ofrece muchas opciones para controlar la forma en la que se ejecuta el bloque. Veámoslas rápidamente.
Lo primero que nos encontramos son los bloques continue
.
Estos bloques se pueden añadir al final de los bucles while
y foreach
y permiten definir bloques de código que se
ejecutará antes de evaluar la condición.
La palabra clave next
nos permite iniciar la siguiente
iteración del bucle, o forzar la ejecución del bloque
continue
en caso de estar definido. En su forma más
sencilla es equivalente al continue
que encontramos en
otros lenguajes. Sin embargo, Perl nos permite asociar etiquetas a los
bucles (útil cuando anidamos bucles) y next
puede ir
acompañado de una de estas etiquetas para indicar cual es el bucle que
queremos continuar.
La palabra clave last
nos permite terminar el bucle, de
la misma forma que break
en otros lenguajes de
programación. Al igual que sucede con next
podemos indicar
una etiqueta para forzar la terminación de un bucle específico.
La palabra clave redo
es similar a
continue
, pero en este caso la condición del bucle no es
re-evaluada. En otras palabras, redo
nos permite volver a
hacer la misma iteración. Al igual que sucede con next
y
last
podemos utilizar una etiqueta para referenciar un
bucle en concreto.
Finalmente, al igual que en C, disponemos de la palabra clave
goto
para saltar a cualquier etiqueta definida en nuestro
programa. Bueno, hace algunas cosas más pero como estamos hablando de
bucles vamos a centrarnos en ese tema.
Podemos crear bucles infinitos en Perl de la misma forma que en C.
Aquí disponemos también de la construcción until
.
for (;;) { # Bucle Infinito
}while (1) {# Bucle infinito
}do {# bucle infinito
until (0); }
Para salir del bucle, utilizaremos la palabra clave
last
. En el caso un bucle do ... until(0)
,
para poder utilizar last
debemos meter todo el bucle en su
propio bloque, de esta forma:
{do
{# Algun codigo
last if (condicion);
until (0);
} }
Muchas gracias a Mark Gardner (@mjg@nerdfight.online en Mastodon) por indicarme como escribir bucles en Perl que no parezcan escritos en C. Además me ha sugerido el uso de perlcritic para evitar bucles estilo C. Muchas gracias!
Resumen
- Perl ofrece bucles
for
,while
,do ... while
,foreach
ygoto
- Perl ofrece bloques
continue
para ejecutar código antes de comprobar la condición - Perl ofrece las instrucciones
next
,last
,goto
yredo
para controla el flujo de ejecución de los bucles. - Perl permite asociar etiquetas a los bucles y utilizar las con
next
,last
,goto
oredo
ofreciendo extra control cuando usamos bucles anidados.
■