Jak wyjść z pętli w Perlu?

295

Próbuję użyć breakinstrukcji w forpętli, ale ponieważ używam również ścisłych napisów w kodzie Perla, pojawia się błąd:

Bareword „break” jest niedozwolony, gdy „ścisłe napisy” są używane na linii ./final.pl w linii 154.

Czy istnieje obejście tego problemu (oprócz wyłączenia ścisłych subskrypcji)?

Mój kod jest sformatowany w następujący sposób:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}
Zain Rizvi
źródło
22
A jeśli nie masz „ścisłych napisów”, zamiast tego dostaniesz błąd w czasie wykonywania, gdy nie może znaleźć napisu o nazwie „przerwa”.
Paul Tomblin,

Odpowiedzi:

441

Och, znalazłem to. Używasz ostatniego zamiast przerwy

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}
Zain Rizvi
źródło
Chociaż jest to jedynie różnica semantyczna i nie sprowadza się do niczego poza spójnością tekstową z poleceniem „next”.
Razor Storm
1
nie wspominając, że „przerwa” jest eksperymentalnym słowem kluczowym w> 5.010, prawda? więc możesz dostać nielegalny błąd poza danym blokiem, a nie, że powinieneś go użyć. Jedyny sposób, który mógłby nawet zadziałać, to użycie pętli while wewnątrz danego bloku, a następnie przerwanie, co teoretycznie działałoby tak, jak chcesz, JEŻELI (i tylko jeśli) dany blok ma tylko pętlę while, i zakładając, że po prostu karmisz, biorąc pod uwagę zmienną skalarną ... ale dlaczego to wszystko działa tylko po to, aby skorzystać z przerwy, jest to (bardzo) zła forma, nie wspominając (bla!) tylko mówiąc, jej „możliwe” po prostu nie jest dobre pomysł, a nie to, co może się
wydawać
25
z jakiegoś powodu zupełnie nie pamiętam tego słowa kluczowego „last”. zawsze kończy się googlingiem w „perl break loop” :(
Thupten
Działa również tak samo dla whilepętli (). my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger,
175

Dodatkowe dane (jeśli masz więcej pytań):

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

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------
Kent Fredric
źródło
2
Tak naprawdę nie potrzebujesz
aparatów
14
Robisz, jeśli masz inny kod tuż po pętli for my $ i, który również chcesz pominąć. Zewnętrzny {} to czysty blok, który sam w sobie jest zabawnym rodzajem pętli, która może być ostatnia / ponów / następna.
ysth
18

Po prostu lastdziałałoby tutaj:

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

Jeśli zagnieżdżono pętle, lastnastąpi wyjście z najbardziej wewnętrznej pętli. W takim przypadku użyj etykiet:

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

Podane lastoświadczenie sprawi, że kompilator wyjdzie z obu pętli. To samo można zrobić w dowolnej liczbie pętli, a etykiety można naprawić w dowolnym miejscu.

Kamal Nayan
źródło
6

Na dużej iteracji lubię używać przerwań. Naciśnij Ctrl+, Caby wyjść:

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

while(!$exitflag) {
    # Do your stuff
}
MortenB
źródło
Rzeczywiście bardzo przydatna sugestia. +1
Keve
@PeterMortensen - działa dobrze w systemie Windows, jedyną rzeczą, o której należy pamiętać w przypadku systemu Windows, może być włączenie automatycznego spłukiwania, jeśli drukujesz do STDOUT '$ | = 1; `
MortenB