Как мне выйти из цикла в Perl?

295

Я пытаюсь использовать breakоператор в forцикле, но так как я также использую строгие подпрограммы в своем коде Perl, я получаю сообщение об ошибке:

Базовое слово "break" не допускается, когда используются "строгие подпрограммы" в строке ./final.pl 154.

Есть ли обходной путь для этого (кроме отключения строгих сабов)?

Мой код отформатирован следующим образом:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}
Заин Ризви
источник
22
И если бы у вас не было «строгих подпрограмм», вы бы получили ошибку во время выполнения, когда не смогли найти подпрограмму «перерыв».
Пол Томблин

Ответы:

441

О, я нашел это. Вы используете последний вместо перерыва

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}
Заин Ризви
источник
Хотя это всего лишь семантическое различие и не намного больше, чем текстовая согласованность с командой «next».
Razor Storm
1
не говоря уже о том, что «break» является экспериментальным ключевым словом в> 5.010, верно? так что вы можете получить недопустимую внешнюю ошибку блока, а не использовать ее. Единственный способ, который даже сработает, - это если вы используете цикл while внутри заданного блока, а затем прервитесь, что в теории будет работать так, как вы хотели, если (и только если) в данном блоке есть только цикл while, и Предполагая, что вы просто кормили, учитывая некоторую скалярную переменную ... но почему все это работает только для того, чтобы использовать разрыв, это (очень) плохая форма, не говоря уже о (бла!) просто сказать, что "возможно", просто не хорошо идея, а не то, что вы думаете, это
osirisgothra
25
по какой-то причине я совершенно не могу вспомнить это ключевое слово 'last'. всегда заканчиваю тем, что прибегаю к помощи 'Perl Break Loop' :(
Thupten
Также работает так же для whileциклов (). my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger
175

Дополнительные данные (если у вас есть дополнительные вопросы):

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

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------
Кент Фредрик
источник
2
На самом деле вам не нужны скобки после FOO:
cjm
14
Вы делаете, если у вас есть другой код сразу после цикла для $ i, который вы также хотите пропустить. Внешний {} - это пустой блок, который сам по себе является забавным видом цикла, который может быть последним / redo / next'd.
ysth
18

Просто lastбудет работать здесь:

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

Если у вас есть вложенные циклы, то lastвыйдите из самого внутреннего цикла. Используйте метки в этом случае:

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

Данное lastутверждение заставит компилятор выйти из обоих циклов. То же самое можно сделать в любом количестве циклов, а метки можно фиксировать где угодно.

Камаль Наян
источник
6

На большой итерации мне нравится использовать прерывания. Просто нажмите Ctrl+, Cчтобы выйти:

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

while(!$exitflag) {
    # Do your stuff
}
MortenB
источник
Действительно очень полезное предложение. +1
Кив
@PeterMortensen - это отлично работает в Windows, единственное, что нужно иметь в виду для окон, это включить автоматическую очистку, если вы печатаете в STDOUT '$ | = 1; `
MortenB