Update
The apparent problem was only due to a typo in my sample script, as noted by @M42. The eval hid the error caused by doing a break without given. The error message in $@ is:
Can't "break" outside a given block
So the case is clear and there is no problem at all. Going to close the question.
Another Update
Seems a little inconsistent, though; warning in one case but not in the other:
$ perl5.12.4 -WE "eval { say 0; say 1 if last; say 2 }; warn if $@; say 3"
0
Can't "break" outside a given block at -e line 1.
...caught at -e line 1.
3
$ perl5.12.4 -WE "eval { say 0; say 1 if last; say 2 }; warn if $@; say 3"
0
Exiting eval via last at -e line 1.
Can't "last" outside a loop block at -e line 1.
...caught at -e line 1.
3
Same output for perl5.14.1.
Wondering why those aren’t compile-time errors anyway. They are syntax errors after all.
And the message says we can’t exit via last or break when the implementation proves we can – the program simply carries on. Should eval really catch such broken code? Just a user wondering …
Original post
In a code review, I just saw a copied/pasted given/when/break where the given/when was deleted and the break was left over. The code compiles and runs without warnings. Which led me to the question:
Does break have defined behaviour outside of given/when ?
I couldn’t find anything authoritative in perlsyn. And I can’t see what would be the break-rationale from the output of the following program:
use 5.010;
use strict;
use warnings;
sub bla {
my @args = @_;
eval {
for ( @args ) {
say;
if ( $_ eq 'blub' ) {
say '==> break';
break;
}
say 'nach if';
}
say 'nach for';
};
say 'eval Ende';
say 'sub Ende';
}
bla qw/ eins zwei blub drei /;
say for '-' x 40;
eval {
say 'im eval';
say '==> break';
break:
say 'immer noch im eval';
};
say 'nach dem eval';
Identical output with 5.10.1, 5.12.4 and 5.14.1. Note in the first example all of eval/for/if are skipped, whereas in the second example eval continues.
eins
nach if
zwei
nach if
blub
==> break
eval Ende
sub Ende
----------------------------------------
im eval
==> break
immer noch im eval
nach dem eval
So is it undefined behaviour? Or do you have any relevant doc pointers?
Put a semicolon instead of a colon after the break instruction
With a colon it is considered as a label.