Bagaimana cara keluar dari loop di Perl?

295

Saya mencoba menggunakan breakpernyataan dalam satu forlingkaran, tetapi karena saya juga menggunakan subs ketat dalam kode Perl saya, saya mendapatkan pesan kesalahan:

Bareword "break" tidak diizinkan saat "subs ketat" digunakan di ./final.pl line 154.

Apakah ada solusi untuk ini (selain menonaktifkan subs ketat)?

Kode saya diformat sebagai berikut:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}
Zain Rizvi
sumber
22
Dan jika Anda tidak memiliki "subs ketat" aktif, Anda akan mendapatkan kesalahan run-time sebagai gantinya ketika tidak dapat menemukan sub bernama "break".
Paul Tomblin

Jawaban:

441

Oh, aku menemukannya. Anda menggunakan yang terakhir sebagai ganti break

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}
Zain Rizvi
sumber
Meskipun ini hanyalah perbedaan semantik dan tidak berarti banyak selain konsistensi tekstual dengan perintah "berikutnya".
Razor Storm
1
belum lagi bahwa 'break' adalah kata kunci eksperimental di> 5,010 kan? jadi Anda mungkin mendapatkan kesalahan blok luar yang diberikan ilegal, bukan bahwa Anda harus menggunakannya. Satu-satunya cara yang bahkan akan bekerja adalah jika Anda menggunakan loop sementara di dalam blok yang diberikan, dan kemudian istirahat, yang secara teori akan bekerja seperti yang Anda inginkan JIKA (dan hanya jika) blok yang diberikan hanya memiliki loop sementara di dalamnya, dan dengan asumsi Anda hanya memberi makan diberikan beberapa variabel skalar ... tapi mengapa semua itu bekerja hanya untuk menggunakan istirahat, itu adalah bentuk (sangat) buruk, belum lagi (bla!) hanya mengatakan, "mungkin" tidak baik ide & bukan apa yang Anda pikirkan
osirisgothra
25
untuk beberapa alasan, saya benar-benar tidak dapat mengingat kata kunci ini 'terakhir'. selalu berakhir dengan googling 'perl break loop' :(
Thupten
Juga, berfungsi sama untuk while() loop. my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger
175

Data tambahan (jika Anda memiliki pertanyaan lain):

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

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------
Kent Fredric
sumber
2
Anda sebenarnya tidak membutuhkan kawat gigi setelah FOO:
cjm
14
Anda lakukan jika Anda memiliki kode lain tepat setelah untuk loop $ i saya yang juga ingin Anda lewati. Bagian luar {} adalah blok kosong, yang dengan sendirinya merupakan semacam loop lucu yang bisa menjadi yang terakhir / ulang / berikutnya.
ysth
18

Cukup lastbekerja di sini:

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

Jika Anda memiliki loop bersarang, maka lastakan keluar dari loop paling dalam. Gunakan label dalam hal ini:

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

Mengingat lastpernyataan akan membuat compiler untuk keluar dari kedua loop. Hal yang sama dapat dilakukan pada sejumlah loop, dan label dapat diperbaiki di mana saja.

Kamal Nayan
sumber
6

Pada iterasi besar saya suka menggunakan interupsi. Cukup tekan Ctrl+ Cuntuk keluar:

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

while(!$exitflag) {
    # Do your stuff
}
MortenB
sumber
Saran yang sangat berguna memang. +1
Keve
@PeterMortensen - ini berfungsi dengan baik di windows, satu-satunya hal yang perlu diingat untuk windows mungkin adalah mengaktifkan autoflush jika Anda mencetak ke STDOUT '$ | = 1; `
MortenB