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;
    }
}

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;
    }
}

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;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------

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.


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
}

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.