So I looked at Perl's source code a bit, and I've found out what really happens. I was right that for had nothing to do with it, but I wasn't entirely correct with respect to the assignment operator.
You called $x a lexical, but that's only semi-true. $x is aliased to undef, so $x is whatever undef returns.
The important bit you're missing follows: When a LHS element of a list assignment is immortal*, Perl pretends the RHS element is on the LHS for the purpose of building the return value.**
$ perl -wle'$x="xx";$y="yy"; $_=uc for ($y)=$x; print "$x$y"' xxXX $ perl -wle'$x="xx";$y="yy"; $_=uc for (undef)=$x; print "$x$y"' XXyy
This means the first and third element of the list returned by the range operator (..) is being returned by the assignment operator, and these are the values you are dumping for the first and third pass of the inner loop.
There's nothing special about the loop wrt undefined values. The new SVs are created by the range operator (..).
* — One of PL_sv_undef, PL_sv_yes, PL_sv_no and PL_sv_placeholder.
** — This isn't documented. This was gleaned from the Perl source code.
In reply to Re^2: list assignment and undef (actual)
by ikegami
in thread list assignment and undef
by ig
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |