Perl can:
perl -le '$d=1; while(1){ $d/=2 and ++$i or last } print "i=$i"'
But not:
perl -le '$d=1; $d/=2 and ++$i or last while 1; print "i=$i"'
which results in:
Can't "last" outside a loop block at -e line 1.
Is this the general case or is it something in this particular statement that prevents last
here? Didn't perl used be able to do last
with statement modifiers (while
/until
/for
at the end) in earlier versions? I tested on v5.26 now and don't have old versions readily available.
Not all statement modifiers.
$ perl -M5.010 -e'last while 1; say "ok"'
Can't "last" outside a loop block at -e line 1.
$ perl -M5.010 -e'last until 0; say "ok"'
Can't "last" outside a loop block at -e line 1.
$ perl -M5.010 -e'last for 1; say "ok"'
ok
Famously, it doesn't work in the special case do BLOCK while EXPR;
either.
$ perl -M5.010 -e'do { last } while 1; say "ok"'
Can't "last" outside a loop block at -e line 1.
I don't know why it works for for
and not the others.
Not new.
$ for v in 10 12 14 16 18 20 22 24 26 28 30 32; do
printf '5.%s:\n' $v
5.${v}t/bin/perl -M5.010 -e'last while 1; say "ok"'
done
5.10:
Can't "last" outside a loop block at -e line 1.
5.12:
Can't "last" outside a loop block at -e line 1.
5.14:
Can't "last" outside a loop block at -e line 1.
5.16:
Can't "last" outside a loop block at -e line 1.
5.18:
Can't "last" outside a loop block at -e line 1.
5.20:
Can't "last" outside a loop block at -e line 1.
5.22:
Can't "last" outside a loop block at -e line 1.
5.24:
Can't "last" outside a loop block at -e line 1.
5.26:
Can't "last" outside a loop block at -e line 1.
5.28:
Can't "last" outside a loop block at -e line 1.
5.30:
Can't "last" outside a loop block at -e line 1.
5.32:
Can't "last" outside a loop block at -e line 1.
Perl doesn't create a redo
able scope for postfix loops as an optimization. Building the scope and making it reinitializable is slightly expensive. That's why we have postfix versions to avoid it.
$ perl -Mdiagnostics -e '$d=1; $d/=2 and ++$i or last while 1; print "i=$i"'
Can't "last" outside a loop block at -e line 1 (#1)
(F) A "last" statement was executed to break out of the current block,
except that there's this itty bitty problem called there isn't a current
block. Note that an "if" or "else" block doesn't count as a "loopish"
block, as doesn't a block given to sort(), map() or grep(). You can
usually double the curlies to get the same effect though, because the
inner curlies will be considered a block that loops once. See
"last" in perlfunc.
Uncaught exception from user code:
Can't "last" outside a loop block at -e line 1.
You can subvert this behavior by wrapping the whole statement in a block which will then become the target for last
.
$ perl -e '$d=1; { $d/=2 and ++$i or last while 1; } print "i=$i"'
i=1074
It's surprising indeed that postfix foreach
accepts last
. The deparse doesn't show anything out of the ordinary.
It seems that postfix foreach
is broken because this happens! :D
$ perl -Mdiagnostics -e '$d=1; $x=2; ($d/=2 and ++$i or last) foreach 1; print "i=$i, x=$x\n"'
i=1, x=2
$ perl -Mdiagnostics -e '$d=1; $x=2; ((my $x=3), $d/=2 and ++$i or last)
foreach 1; print "i=$i, x=$x\n"'
Name "main::x" used only once: possible typo at -e line 1 (#1)
(W once) Typographical errors often show up as unique variable
names. If you had a good reason for having a unique name, then
just mention it again somehow to suppress the message. The our
declaration is also provided for this purpose.
NOTE: This warning detects package symbols that have been used
only once. This means lexical variables will never trigger this
warning. It also means that all of the package variables $c, @c,
%c, as well as *c, &c, sub c{}, c(), and c (the filehandle or
format) are considered the same; if a program uses $c only once
but also uses any of the others it will not trigger this warning.
Symbols beginning with an underscore and symbols using special
identifiers (q.v. perldata) are exempt from this warning.
Use of uninitialized value $x in concatenation (.) or string at -e line 1 (#2)
(W uninitialized) An undefined value was used as if it were already
defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
To suppress this warning assign a defined value to your variables.
To help you figure out what was undefined, perl will try to tell you
the name of the variable (if any) that was undefined. In some cases
it cannot do this, so it also tells you what operation you used the
undefined value in. Note, however, that perl optimizes your program
and the operation displayed in the warning may not necessarily appear
literally in your program. For example, "that $foo" is usually
optimized into "that " . $foo, and the warning will refer to the
concatenation (.) operator, even though there is no . in
your program.
i=1, x=
Minimalist example:
$ perl -W -e '$x=2; (my $x=3) foreach 1; print "x=$x\n"'
Name "main::x" used only once: possible typo at -e line 1.
Use of uninitialized value $x in concatenation (.) or string at -e line 1.
x=
I tried this on 5.22 and 5.30.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With