• Publicidad

[Duda]last, next, y redo

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

[Duda]last, next, y redo

Notapor erv-Z » 2010-01-15 15:43 @696

Hola, tengo una duda: quisiera saber para qué sirven las funciones last, next, y redo. Estaba buscándolos en la sección tutoriales y no lo encontré.
erv-Z
Perlero nuevo
Perlero nuevo
 
Mensajes: 158
Registrado: 2009-07-25 13:00 @583

Publicidad

Re: [Duda]last, next, y redo

Notapor explorer » 2010-01-15 21:30 @937

El last termina el bucle actual:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@a = qw( a f t s 3 d );
for (@a) {
    last if /\d/;   # terminamos si hemos encontrado un número
    print "$_\n";
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El next pasa al ciclo siguiente del bucle:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@a = qw( a f t s 3 d );
for (@a) {
    next if /\d/;   # pasamos al siguiente si es un número
    print "$_\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El redo vuelve a ejecutar la condición de parada del bucle:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@a = qw( a f t s 3 d );
for ($i = 0; $i < @a; $i++) {
    $_ = $a[$i];
    if (/\d/) {
        $i++;       # pasamos al siguiente si es un número
        redo;       # pero antes comprobamos si hemos terminado
    }
    print "$_\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Esto sirve para todos las sentencias de bucles, salvo do{}, que hay que hacer un truco para que funcione.

Además, también pueden ir acompañadas de una etiqueta, con lo que se puede saltar el control, desde un bucle interno a un bucle externo.

Más información en perldoc perlsyn, a partir de la sección "Compound Statements" y la siguiente "Loop Control".
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: [Duda]last, next, y redo

Notapor erv-Z » 2010-01-16 13:26 @601

Entendido, aunque el next reemplaza al redo. Sería bueno que lo pusieras en tutoriales.
erv-Z
Perlero nuevo
Perlero nuevo
 
Mensajes: 158
Registrado: 2009-07-25 13:00 @583

Re: [Duda]last, next, y redo

Notapor explorer » 2010-01-16 14:33 @648

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:
Sintáxis: [ Descargar ] [ Ocultar ]
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:
Sintáxis: [ Descargar ] [ Ocultar ]
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:
Sintáxis: [ Descargar ] [ Ocultar ]
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.001 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.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my $cadena = 'Una larga cadena de  la     que    le   sobran   muchos   blancos.    ';
  7. print "[$cadena]\n";
  8.  
  9. for (my $i = 0; $i < length $cadena; $i++) {
  10.     # Si el carácter $i-ésimo es un blanco, y, el anterior, también lo era...
  11.     if (substr($cadena, $i, 1) eq ' '  and  substr($cadena, $i-1, 1) eq ' ') {
  12.         substr $cadena, $i, 1,    '';   # lo quitamos
  13. #        redo;
  14.     }
  15. }
  16. print "[$cadena]\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

La salida del programa será:
Sintáxis: [ Descargar ] [ Ocultar ]
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:
Sintáxis: [ Descargar ] [ Ocultar ]
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.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: [Duda]last, next, y redo

Notapor erv-Z » 2010-01-16 15:43 @696

Um... ok ahora me quedo más claro.
erv-Z
Perlero nuevo
Perlero nuevo
 
Mensajes: 158
Registrado: 2009-07-25 13:00 @583


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 17 invitados