321

I'm trying to use a break statement in a for loop, but since I'm also using strict subs in my Perl code, I'm getting an error saying:

Bareword "break" not allowed while "strict subs" in use at ./final.pl line 154.

Is there a workaround for this (besides disabling strict subs)?

My code is formatted as follows:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Zain Rizvi
  • 23,586
  • 22
  • 91
  • 133
  • 24
    And if you didn't have "strict subs" on, you would have gotten a run-time error instead when it couldn't find a sub named "break". – Paul Tomblin Nov 19 '08 at 20:43

5 Answers5

472

Oh, I found it. You use last instead of break

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

It's also described under Loop Control in "perlsyn(1)" (man perlsyn on UNIX-like).

U. Windl
  • 3,480
  • 26
  • 54
Zain Rizvi
  • 23,586
  • 22
  • 91
  • 133
  • Though this is merely a semantic difference and doesn't amount to much else other than textual consistency with the "next" command. – Razor Storm Jul 08 '10 at 20:14
  • 1
    not to mention that 'break' is an experimental keyword in >5.010 right? so you might get an illegal outside given block error, not that you should use it. The only way that would even work is if you used a while loop inside a given block, and then break, which in theory would work the way you wanted IF (and only if) the given block only had the while loop in it, and assuming you were just feeding given some scalar variable... but why do all that work just to use a break, it is (very) bad form, not to mention (blah!)just saying, its "possible" just not a good idea & not what you may think it is – osirisgothra Sep 01 '14 at 15:50
  • 33
    for some reason, i am completely unable to remember this keyword 'last'. always end up googling 'perl break loop' :( – Thupten Sep 08 '15 at 04:50
  • 1
    Also, works the same for `while`() loops. `my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"` – HoldOffHunger Jul 17 '18 at 19:06
178

Additional data (in case you have more questions):

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

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kent Fredric
  • 56,416
  • 14
  • 107
  • 150
  • 2
    You don't actually need the braces after FOO: – cjm Nov 20 '08 at 01:21
  • 15
    You do if you have other code just after the for my $i loop that you also want to skip. The outer {} is a bare block, which is itself a funny kind of loop that can be last/redo/next'd. – ysth Nov 20 '08 at 02:23
25

Simply last would work here:

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

If you have nested loops, then last will exit from the innermost loop. Use labels in this case:

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

Given a last statement will make the compiler to come out from both the loops. The same can be done in any number of loops, and labels can be fixed anywhere.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kamal Nayan
  • 1,890
  • 21
  • 34
5

On a large iteration I like using interrupts. Just press Ctrl + C to quit:

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

while(!$exitflag) {
    # Do your stuff
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MortenB
  • 2,749
  • 1
  • 31
  • 35
  • @PeterMortensen - this works fine in windows, the only thing to keep in mind for windows may be to turn on autoflush if you print to STDOUT '$|=1;` – MortenB Jun 05 '20 at 10:31
3

For Perl one-liners with implicit loops (using -n or -p command line options), use last or last LINE to break out of the loop that iterates over input records. For example, these simple examples all print the first 2 lines of the input:

echo 1 2 3 4 | xargs -n1 | perl -ne 'last if $. == 3; print;'
echo 1 2 3 4 | xargs -n1 | perl -ne 'last LINE if $. == 3; print;'
echo 1 2 3 4 | xargs -n1 | perl -pe 'last if $. == 3;'
echo 1 2 3 4 | xargs -n1 | perl -pe 'last LINE if $. == 3;'

All print:

1
2

The perl one-liners use these command line flags:
-e : tells Perl to look for code in-line, instead of in a file.
-n : loop over the input one line at a time, assigning it to $_ by default.
-p : same as -n, also add print after each loop iteration over the input.

SEE ALSO:

last docs
last, next, redo, continue - an illustrated example
perlrun: command line switches docs


More examples of last in Perl one-liners:

Break one liner command line script after first match
Print the first N lines of a huge file

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47