It seems to me that's because of
if (cxix < cxstack_ix) dounwind(cxix);

in PP(pp_next) and PP(pp_redo) in pp_ctl.c. Debugging reveals an additional BLOCK frame which is built around the scope in which a next or redo is found:

qwurx [shmem] ~ > perl -D4 { print("norm: "); local $_ = 'fred'; for (; /./g ; print("<$&>\n"),1) { } print("\n"); } { print("next: "); local $_ = 'fred'; for (; /./g ; print("<$&>\n"),1) { next } print("\n"); } __END__ (some lines skipped) EXECUTING... (next.pl:0) ENTER scope 2 at pp_hot.c:1694 Entering block 0, type BLOCK (next.pl:2) ENTER scope 3 at pp_ctl.c:1798 (next.pl:2) ENTER scope 4 at pp_ctl.c:1800 Entering block 1, type LOOP (next.pl:4) ENTER scope 5 at pp_ctl.c:1798 (next.pl:4) ENTER scope 6 at pp_ctl.c:1800 Entering block 2, type LOOP norm: <f> <r> <e> <d> (next.pl:4) POPBLOCK scope 6 at pp_ctl.c:1817 Leaving block 2, type LOOP (next.pl:4) LEAVE scope 6 at pp_ctl.c:1843 (next.pl:4) LEAVE scope 5 at pp_ctl.c:1844 (next.pl:2) POPBLOCK scope 4 at pp_ctl.c:1817 Leaving block 1, type LOOP (next.pl:2) LEAVE scope 4 at pp_ctl.c:1843 (next.pl:2) LEAVE scope 3 at pp_ctl.c:1844 (next.pl:8) ENTER scope 3 at pp_ctl.c:1798 (next.pl:8) ENTER scope 4 at pp_ctl.c:1800 Entering block 1, type LOOP (next.pl:10) ENTER scope 5 at pp_ctl.c:1798 (next.pl:10) ENTER scope 6 at pp_ctl.c:1800 Entering block 2, type LOOP (next.pl:10) ENTER scope 7 at pp_hot.c:1694 Entering block 3, type BLOCK (next.pl:10) (Found loop #2) Unwinding block 3, type BLOCK (next.pl:10) TOPBLOCK scope 6 at pp_ctl.c:2073 next: <> (next.pl:10) ENTER scope 7 at pp_hot.c:1694 Entering block 3, type BLOCK (next.pl:10) (Found loop #2) Unwinding block 3, type BLOCK (next.pl:10) TOPBLOCK scope 6 at pp_ctl.c:2073 <> (next.pl:10) ENTER scope 7 at pp_hot.c:1694 Entering block 3, type BLOCK (next.pl:10) (Found loop #2) Unwinding block 3, type BLOCK (next.pl:10) TOPBLOCK scope 6 at pp_ctl.c:2073 <> (next.pl:10) ENTER scope 7 at pp_hot.c:1694 Entering block 3, type BLOCK (next.pl:10) (Found loop #2) Unwinding block 3, type BLOCK (next.pl:10) TOPBLOCK scope 6 at pp_ctl.c:2073 <> (next.pl:10) POPBLOCK scope 6 at pp_ctl.c:1817 Leaving block 2, type LOOP (next.pl:10) LEAVE scope 6 at pp_ctl.c:1843 (next.pl:10) LEAVE scope 5 at pp_ctl.c:1844 (next.pl:8) POPBLOCK scope 4 at pp_ctl.c:1817 Leaving block 1, type LOOP (next.pl:8) LEAVE scope 4 at pp_ctl.c:1843 (next.pl:8) LEAVE scope 3 at pp_ctl.c:1844 (next.pl:0) POPBLOCK scope 2 at pp_hot.c:1804 Leaving block 0, type BLOCK (next.pl:0) LEAVE scope 2 at pp_hot.c:1843 (next.pl:0) Setting up jumplevel bfdb9400, was 816619c (next.pl:0) LEAVE scope 1 at perl.c:645

update: Things become more clear if we change the 'next' block as follows:

{ print("next: "); local $_ = 'fred'; for (; /./g ; print("<$&>\n"),1) { print "<$&>\n"; next; } print("\n"); }

which yields

EXECUTING... (next.pl:0) ENTER scope 2 at pp_hot.c:1694 Entering block 0, type BLOCK (next.pl:2) ENTER scope 3 at pp_ctl.c:1798 (next.pl:2) ENTER scope 4 at pp_ctl.c:1800 Entering block 1, type LOOP (next.pl:4) ENTER scope 5 at pp_ctl.c:1798 (next.pl:4) ENTER scope 6 at pp_ctl.c:1800 Entering block 2, type LOOP (next.pl:4) ENTER scope 7 at pp_hot.c:1694 Entering block 3, type BLOCK next: <f> (next.pl:6) (Found loop #2) Unwinding block 3, type BLOCK (next.pl:6) TOPBLOCK scope 6 at pp_ctl.c:2073 <> (next.pl:4) ENTER scope 7 at pp_hot.c:1694 Entering block 3, type BLOCK <r> (next.pl:6) (Found loop #2) Unwinding block 3, type BLOCK (next.pl:6) TOPBLOCK scope 6 at pp_ctl.c:2073 <> ...

So, the print in the for() condition is in scope 6, while the print just before next is in scope 7...

<update>

What is happening in this loop is that the /./g is evaluated in scope 6. Then the inner loop block is executed (scope 7, block 3). Then that block is left, and all lexical (and match) variables are restored. After that the last part of the for(;;) conditional construct is executed - the print("<$&>\n"),1 - at which time $& happens to have been reset already, because the inner scope has been left, as can be seen with the following snippet:

{ print("next: "); local $_ = 'fred'; for ( print "begin\n"; /./g, print("1<$&>\n") and $& ? 1 : 0 ; print("2<$&>\n"),1) { print "3<$&>\n"; next; } print("\n"); } __END__ next: begin 1<f> 3<f> 2<> 1<r> 3<r> 2<> 1<e> 3<e> 2<> 1<d> 3<d> 2<> 1<>

Run it under -D4 :-)

</update>

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

In reply to Re^2: Does redo create a new dynamic scope? by shmem
in thread Does redo create a new dynamic scope? by brian_d_foy

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.