in reply to Unexpected behavior of '..' lists
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".
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Unexpected behaviour with constant lists and foreach (and closures?)
by Crackers2 (Parson) on Jul 20, 2006 at 18:42 UTC | |
by ikegami (Patriarch) on Jul 20, 2006 at 18:43 UTC | |
by diotalevi (Canon) on Jul 20, 2006 at 19:32 UTC | |
by ysth (Canon) on Jul 21, 2006 at 19:22 UTC |