I'm a little surprised by the following behavior, I'm chaining generators, such that iterators can be combined:
my $call=0; sub generator (;$) { my $inner_iter=shift; my $dummy; $outer_iter=sub {}; # $outer_iter=sub { $inner_iter->() }; # $outer_iter=sub { $dummy++ }; $call++; print "Call Nr $call\n"; if ($inner_iter){ print $inner_iter."\n"; if ( $inner_iter eq $outer_iter) { print "ERROR !!!\n" } } return $outer_iter; } print generator generator;
I expected that the second anonymous sub $outer_iter to be different from the first, which is also present in the same scope as $inner_iter and hasn't been destroyed yet.
But that's not the case:
/usr/bin/perl -w /tmp/tst.pl Call Nr 1 Call Nr 2 CODE(0x90fa080) ERROR !!! CODE(0x90fa080)
Only uncommenting line 8 or 9 helps, such that an outer variable belongs to the closure of $outer_iter.
Call Nr 1 Call Nr 2 CODE(0x9604880) CODE(0x9623210)
Seems to be an optimization from Perl, kind of constant folding of subs which aren't closures.
So I already have a work around ...
... but out of curiosity, is there any other way to force the creation of a really different instance of a sub, even with the same body but without creating a closure?
Cheers Rolf
sub gen_arr { my $inner_arr=shift; print my $outer_arr=[]; return $outer_arr; } gen_arr gen_arr; #prints ARRAY(0xa179880)ARRAY(0xa179760)
In reply to Avoiding reference of sub optimization by LanX
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |