Como faço para sair de um loop no Perl?

295

Estou tentando usar uma breakinstrução em um forloop, mas como também estou usando subs estritos no meu código Perl, estou recebendo um erro dizendo:

Não é permitida a quebra de palavras de barra enquanto "subs estritos" são utilizados na linha 154 .ff.pl.

Existe uma solução alternativa para isso (além de desativar subs estritos)?

Meu código está formatado da seguinte maneira:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}
Zain Rizvi
fonte
22
E se você não tivesse "subs estritos" ativados, teria recebido um erro em tempo de execução quando não conseguisse encontrar um sub nomeado "break".
Paul Tomblin 19/11/2008

Respostas:

441

Oh, eu encontrei. Você usa por último em vez de pausa

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}
Zain Rizvi
fonte
Embora isso seja apenas uma diferença semântica e não represente muito mais que consistência textual com o comando "next".
Navalha Tempestade
1
sem mencionar que 'break' é uma palavra-chave experimental em> 5.010, certo? então você pode receber um erro ilegal fora do bloco, não que você deva usá-lo. A única maneira de funcionar seria se você usasse um loop while dentro de um determinado bloco e depois quebrasse, o que, em teoria, funcionaria da maneira que você queria SE (e somente se) o bloco fornecido tivesse apenas o loop while, e supondo que você estava apenas alimentando, dada uma variável escalar ... mas por que todo esse trabalho funciona apenas para fazer uma pausa, é uma forma (muito) ruim, sem mencionar (blá!) apenas dizendo, é "possível", mas não é bom ideia e não o que você pode pensar que é
osirisgothra
25
por algum motivo, não consigo me lembrar dessa palavra-chave 'last'. sempre acabo pesquisando 'perl break loop' :(
Thupten 8/15
Além disso, funciona da mesma forma para whileloops (). my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger 17/07/2018
175

Dados adicionais (caso você tenha mais perguntas):

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

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------
Kent Fredric
fonte
2
Na verdade, você não precisa do aparelho depois do FOO:
cjm
14
Você o faz se tiver outro código logo após o loop for $ i que também deseja pular. O externo {} é um bloco simples, que por si só é um tipo engraçado de loop que pode ser o último / refazer / próximo.
ysth 20/11/08
18

Simplesmente lastfuncionaria aqui:

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

Se você tiver loops aninhados, lastsairá do loop mais interno. Use etiquetas neste caso:

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

Dada uma lastdeclaração, o compilador sairá dos dois loops. O mesmo pode ser feito em qualquer número de loops e as etiquetas podem ser fixadas em qualquer lugar.

Kamal Nayan
fonte
6

Em uma iteração grande, gosto de usar interrupções. Basta pressionar Ctrl+ Cpara sair:

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

while(!$exitflag) {
    # Do your stuff
}
MortenB
fonte
Sugestão muito útil mesmo. 1
Keve
@ PeterMortensen - isso funciona bem no Windows, a única coisa a ter em mente no Windows pode ser ativar o autoflush se você imprimir em STDOUT '$ | = 1; `
MortenB