¿Cómo salgo de un bucle en Perl?

295

Estoy tratando de usar una breakdeclaración en un forbucle, pero como también estoy usando subs estrictos en mi código Perl, recibo un error que dice:

La palabra "break" sin palabra no está permitida mientras se usan "subs estrictos" en ./final.pl línea 154.

¿Hay alguna solución para esto (además de deshabilitar los subs estrictos)?

Mi código tiene el siguiente formato:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}
Zain Rizvi
fuente
22
Y si no tuviera "subs estrictos", habría recibido un error de tiempo de ejecución en su lugar cuando no pudiera encontrar un sub llamado "break".
Paul Tomblin

Respuestas:

441

Oh, lo encontre. Usas último en lugar de descanso

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}
Zain Rizvi
fuente
Aunque esto es simplemente una diferencia semántica y no equivale a otra cosa que no sea la coherencia textual con el comando "siguiente".
Razor Storm
1
sin mencionar que 'break' es una palabra clave experimental en> 5.010 ¿verdad? por lo que puede obtener un error de bloqueo ilegal fuera de un determinado bloque, no es que deba usarlo. La única forma que incluso funcionaría es si usaras un ciclo while dentro de un bloque dado, y luego lo rompieras, lo que en teoría funcionaría de la manera que quisieras IF (y solo si) el bloque dado solo tenía el ciclo while, y asumiendo que solo se estaba alimentando dada alguna variable escalar ... pero ¿por qué hacer todo ese trabajo solo para usar un descanso? ​​Es una forma (muy) mala, sin mencionar (¡bla!) solo decir que es "posible" simplemente no es bueno. idea y no lo que crees que es
osirisgothra
25
por alguna razón, soy completamente incapaz de recordar esta palabra clave 'último'. siempre termina buscando en Google 'perl break loop' :(
Thupten
Además, funciona igual para los whilebucles (). my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger
175

Datos adicionales (en caso de que tenga más preguntas):

FOO: {
       for my $i ( @listone ){
          for my $j ( @listtwo ){
                 if ( cond( $i,$j ) ){

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------
Kent Fredric
fuente
2
En realidad no necesita los frenos después de FOO:
cjm
14
Lo tiene si tiene otro código justo después del bucle $ my que también desea omitir. El exterior {} es un bloque desnudo, que es en sí mismo un tipo divertido de bucle que puede ser el último / rehacer / siguiente.
ysth
18

Simplemente lastfuncionaría aquí:

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}

Si tiene bucles anidados, lastsaldrá del bucle más interno. Use etiquetas en este caso:

LBL_SCORE: {
    for my $entry1 (@array1) {
        for my $entry2 (@array2) {
            if ($entry1 eq $entry2) { # Or any condition
                last LBL_SCORE;
            }
        }
    }
 }

Dada una lastdeclaración hará que el compilador salga de ambos bucles. Lo mismo se puede hacer en cualquier número de bucles, y las etiquetas se pueden arreglar en cualquier lugar.

Kamal Nayan
fuente
6

En una iteración grande, me gusta usar interrupciones. Simplemente presione Ctrl+ Cpara salir:

my $exitflag = 0;
$SIG{INT} = sub { $exitflag=1 };

while(!$exitflag) {
    # Do your stuff
}
MortenB
fuente
Muy útil sugerencia de hecho. +1
Keve
@PeterMortensen: esto funciona bien en Windows, lo único que debe tener en cuenta para Windows puede ser activar el enjuague automático si imprime en STDOUT '$ | = 1; `
MortenB