No, el
next no reemplaza al
redo.
El
next pide que se ejecute la
siguiente vuelta del bucle, mientras que
redo pide que se vuelva a ejecutar el
mismo ciclo.
next se suele usar, normalmente, como filtrado:
Using perl Syntax Highlighting
for (qw(lista de valores
)) {
if (/^[a
-f
]) {
next;
}
print "$_ ";
}
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
O también para saltar al siguiente ciclo porque no es necesario que se ejecuten el resto de sentencias que hay dentro del bucle:
Using perl Syntax Highlighting
for (qw(lista de muchos valores que son muy largos
y aburridos
)) {
print "$_\n";
if (/^[a
-f
]) {
next;
}
print uc($_), "\n";
}
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Se puede usar incluso para saltar al siguiente ciclo de un bucle interior a otro:
Using perl Syntax Highlighting
BUSCARDRAGON
:
for my $columna (0
.. $#columnas) {
for my $fila (0
.. $#filas) {
my $contenido_celda = celda
($fila, $columna);
if ($contenido_celda->{nombre
} eq 'agua') {
next BUSCARDRAGON
;
}
# ...
}
}Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
En cambio,
redo volverá a ejecutar el actual bucle. Esto se suele usar para situaciones en las cuales estás recorriendo una estructura de datos, y te encuentras con un elemento que necesita ser alterado, antes de pasar al siguiente. Ese elemento lo cambiamos, y ejecutamos
redo para que vuelva a empezar el mismo ciclo, comprobando las misma condición, para ver si el elemento coincide con los demás, y, si es así, continuar.
Por ejemplo, supongamos que tenemos que hacer un programa que elimine los espacios en blanco sobrantes de una cadena de caracteres.
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
my $cadena = 'Una larga cadena de la que le sobran muchos blancos. ';
print "[$cadena]\n";
for (my $i = 0; $i < length $cadena; $i++) {
# Si el carácter $i-ésimo es un blanco, y, el anterior, también lo era...
if (substr($cadena, $i, 1) eq ' ' and substr($cadena, $i-1, 1) eq ' ') {
substr $cadena, $i, 1, ''; # lo quitamos
# redo;
}
}
print "[$cadena]\n";
Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
La salida del programa será:
Using text Syntax Highlighting
[Una larga cadena de la que le sobran muchos blancos. ]
[Una larga cadena de la que le sobran muchos blancos. ]
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
Vemos que se ha resuelto el problema, pero no completamente. ¿Por qué? Pues porque cuando ejecutamos el substr() que elimina el carácter en blanco, $i apunta en ese momento al carácter siguiente. Y al final del bucle, se incrementa $i para apuntar al "siguiente", pero en realidad, estaremos apuntando a dos caracteres más allá de donde estábamos.
En cambio, si descomentamos la línea del
redo, estamos diciendo que la estructura de datos ($cadena) sobre la que estamos trabajando, ha cambiado, por lo que es necesario volver a comprobar la condición de parada y volver a iniciar el ciclo actual. En efecto, la condición no se cumple por lo que seguimos dentro del bucle, y $i no es incrementado, por lo que está apuntando en la misma posición de
antes, por lo que estamos mirando el carácter que estaba a la derecha del carácter en blanco que eliminamos.
La salida ahora, es un poco más correcta:
Using text Syntax Highlighting
[Una larga cadena de la que le sobran muchos blancos. ]
[Una larga cadena de la que le sobran muchos blancos. ]
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
En este
otro hilo hemos dado otro ejemplo de
last,
next y
redo.
P.D. Sí, ya sé que con un exp. reg. se quitan más fácil los blancos sobrantes, pero... estoy explicando otra cosa.