Come posso uscire da un ciclo in Perl?


295

Sto cercando di utilizzare breakun'istruzione in un forciclo, ma poiché sto anche usando sottotitoli rigidi nel mio codice Perl, ricevo un errore che dice:

La parola chiave "break" non è consentita mentre "subs rigorosi" è in uso alla riga 154/final.pl.

Esiste una soluzione alternativa per questo (oltre a disabilitare i sottotitoli rigidi)?

Il mio codice è formattato come segue:

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

22
E se non avessi "sottotitoli rigidi" attivi, avresti invece ricevuto un errore di runtime quando non è stato possibile trovare un sottotitolo chiamato "break".
Paul Tomblin,

Risposte:


441

Oh, l'ho trovato. Usi last invece di break

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

Anche se questa è semplicemente una differenza semantica e non equivale a molto altro che alla coerenza testuale con il comando "successivo".
Razor Storm,

1
per non dire che "break" è una parola chiave sperimentale in> 5.010 giusto? quindi potresti ricevere un errore di blocco esterno dato illegale, non che dovresti usarlo. L'unico modo in cui funzionerebbe anche se si usasse un ciclo while all'interno di un determinato blocco, e poi si rompa, che in teoria funzionerebbe nel modo desiderato SE (e solo se) il blocco dato avesse solo il ciclo while in esso, e supponendo che tu stia solo nutrendo dato una variabile scalare ... ma perché tutto ciò che funziona solo per usare una pausa, è (molto) forma cattiva, per non parlare di (blah!) solo dicendo, il suo "possibile" semplicemente non è un bene idea e non quello che potresti pensare che sia
osirisgothra,

25
per qualche motivo, non sono del tutto in grado di ricordare questa parola chiave "ultimo". finisci sempre per cercare 'perl break loop' su google :(
Thupten

Inoltre, funziona allo stesso modo per i whileloop (). my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger,

175

Dati aggiuntivi (in caso di ulteriori domande):

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

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------

2
In realtà non hai bisogno delle parentesi graffe dopo l'
UFAM

14
Lo fai se hai un altro codice subito dopo il ciclo for my $ i che vuoi saltare. Il {} esterno è un blocco nudo, che è esso stesso un tipo divertente di loop che può essere last / redo / next'd.
ysth

18

Funzionerebbe semplicemente lastqui:

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

Se hai loop nidificati, lastuscirà dal loop più interno. Usa le etichette in questo caso:

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

Una lastdichiarazione data farà uscire il compilatore da entrambi i loop. Lo stesso può essere fatto in qualsiasi numero di loop e le etichette possono essere riparate ovunque.


6

In una grande iterazione mi piace usare gli interrupt. Premi Ctrl+ Cper uscire:

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

while(!$exitflag) {
    # Do your stuff
}

Suggerimento davvero utile. +1
Keve,

@PeterMortensen - questo funziona bene su Windows, l'unica cosa da tenere a mente per Windows potrebbe essere quella di attivare l'autoflush se si stampa su STDOUT '$ | = 1; `
MortenB
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.