in reply to evaluation strategy of perl

the problem here is that $i is declared only once and at the end of the for loop it has the value 3. i think what you want is something like this:
foreach my $i (0 .. 2) { push @d, sub { print "$i\n" }; }
in each iteration a new variable $i is created. the old $i (from the former loop iteration) is no longer accessible via $i, but because there is a subroutine referencing it, it is not garbage collected.