Wie breche ich in Perl aus einer Schleife aus?

295

Ich versuche, eine breakAnweisung in einer forSchleife zu verwenden, aber da ich in meinem Perl-Code auch strenge Subs verwende, wird die folgende Fehlermeldung angezeigt:

Barwort "break" ist nicht zulässig, während "strict subs" in ./final.pl Zeile 154 verwendet wird.

Gibt es eine Problemumgehung dafür (außer das Deaktivieren strenger Subs)?

Mein Code ist wie folgt formatiert:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}
Zain Rizvi
quelle
22
Und wenn Sie keine "strengen Subs" aktiviert hätten, hätten Sie stattdessen einen Laufzeitfehler erhalten, wenn kein Sub mit dem Namen "break" gefunden werden konnte.
Paul Tomblin

Antworten:

441

Oh, ich habe es gefunden. Sie verwenden last anstelle von break

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}
Zain Rizvi
quelle
Dies ist jedoch nur ein semantischer Unterschied und bedeutet nichts anderes als die Textkonsistenz mit dem Befehl "next".
Rasiermesser Sturm
1
ganz zu schweigen davon, dass 'break' ein experimentelles Schlüsselwort in> 5.010 ist, oder? Sie könnten also einen unzulässigen externen Blockfehler erhalten, nicht dass Sie ihn verwenden sollten. Der einzige Weg, der überhaupt funktionieren würde, wäre, wenn Sie eine while-Schleife innerhalb eines bestimmten Blocks verwenden und dann brechen würden, was theoretisch so funktionieren würde, wie Sie es wollten, WENN (und nur wenn) der angegebene Block nur die while-Schleife enthält, und Angenommen, Sie haben nur mit einer skalaren Variablen gefüttert ... aber warum funktioniert das alles nur, um eine Pause zu verwenden? Es ist eine (sehr) schlechte Form, ganz zu schweigen von (bla!), nur zu sagen, es ist "möglich", nur nicht gut Idee & nicht, was Sie vielleicht denken, es ist
Osirisgothra
25
Aus irgendeinem Grund kann ich mich an dieses Schlüsselwort 'last' nicht erinnern.
Thupten
Funktioniert auch für while() Schleifen. my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger
175

Zusätzliche Daten (falls Sie weitere Fragen haben):

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

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------
Kent Fredric
quelle
2
Sie brauchen die Zahnspange nach FOO nicht wirklich:
cjm
14
Sie tun dies, wenn Sie kurz nach der for my $ i-Schleife einen anderen Code haben, den Sie ebenfalls überspringen möchten. Das äußere {} ist ein nackter Block, der selbst eine lustige Art von Schleife ist, die last / redo / next'd sein kann.
20.
18

lastWürde hier einfach funktionieren:

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

Wenn Sie verschachtelte Schleifen haben, lastwird die innerste Schleife verlassen. Verwenden Sie in diesem Fall Etiketten:

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

Wenn eine lastAnweisung angegeben wird, wird der Compiler aus beiden Schleifen ausgegeben. Das Gleiche kann in einer beliebigen Anzahl von Schleifen durchgeführt werden, und Beschriftungen können überall befestigt werden.

Kamal Nayan
quelle
6

Bei einer großen Iteration verwende ich gerne Interrupts. Drücken Sie einfach Ctrl+, Cum das Programm zu beenden:

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

while(!$exitflag) {
    # Do your stuff
}
MortenB
quelle
Sehr nützlicher Vorschlag in der Tat. +1
Keve
@PeterMortensen - dies funktioniert gut in Windows. Das einzige, was Sie bei Windows beachten sollten, ist das Aktivieren der automatischen Spülung, wenn Sie in STDOUT '$ | = 1; `
MortenB