in reply to last in do vs last in while/for

No, do {} while is a single statement, using while as postfix control. It's the same as print while() or sleep while()... Perl sees the do {} block as one statement (do) which happens to take a code block as an argument, and you can't use loop control statements within that block.

You can use do with other postfix controls which are decidedly un-looplike, for example:
do { print "Hello!"; } if (1);
while() {} on the other hand is a genuine loop.

Replies are listed 'Best First'.
Re^2: last in do vs last in while/for
by zwon (Abbot) on Mar 04, 2009 at 19:48 UTC

    Ok, but why works the following:

    $ perl -le'do { print $i++; last if $i>5 } for (1..10); print "end"' 0 1 2 3 4 5 end
      Seems that postfix for actually creates a loop. I wonder if that has always been the case.
      $ perl -MO=Concise,-exec -e'while (foo()) { bar() }' 3 <{> enterloop(next->8 last->d redo->4) v $ perl -MO=Concise,-exec -e'bar() while foo()' $ perl -MO=Concise,-exec -e'do { bar() } while foo()' $ perl -MO=Concise,-exec -e'for (foo()) { bar() }' 8 <{> enteriter(next->d last->g redo->9) lK $ perl -MO=Concise,-exec -e'bar() for foo()' 9 <{> enteriter(next->d last->g redo->a) lK

      (Output filtered using grep 'enterloop\|enteriter')

      bar() while foo() uses a goto instead. It is implemented almost identically to:

      LOOP_START: ( bar() ), goto LOOP_START if foo();

      do { bar() } while foo() is not readily representable in Perl, but it doesn't use a loop either. The closest I can get is

      LOOP_START: do { bar() }; goto LOOP_START unless foo();

      But yes, the answer is "Implementation Details". There's no real reason for it not to work except backwards compatibility.