Closures are not relevant here:
#for (1..2) { # foreach my $x (0) { print $x++; } # Error! #} for (1..2) { foreach my $x (0..1) { print $x++; } # 01, 01 } for (1..2) { foreach my $x (0..1,5..6) { print $x++; } # 0156, 1267 }
I'm not sure why this only happens if you combine several ranges.
Actually, it also applies with just a single range:
for (1..2) { print map { $_++ } 0..1; # 01, 12 } for (1..2) { print map { $_++ } 0..1,5..6; # 0156, 1267 }
Keep in mind that foreach (expr1..expr2) is optimized into a counting loop, so $x is not an alias to a constant list in the case of foreach my $x (0..1).
You've apparently found an optimization. If you turn 0..1,5..6 into a non-constant expression, the expression rebuilds the list every time:
for (1..2) { foreach my $x (map $_, 0..1,5..6) { print $x++; } # 0156, 0156 }
Another fix is:
for (1..2) { foreach (0..1,5..6) { my $x = $_; print $x++; } # 0156, 0156 }
Personally I'd consider the fact that lists generated from ranges aren't read-only a bug.
Aye. Lists deemed constant for optimization purposes should have its values flagged read-only.
Update: Added a bit to make my explanations easier to follow. Adjusted my code to match the changes the OP did in his "Update 2".
In reply to Re: Unexpected behaviour with constant lists
by ikegami
in thread Unexpected behavior of '..' lists
by Crackers2
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |