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}
|