Borrowing the the term form a Javascript, what is the 'best practice' way to IIFE in perl?
My test code below is a simple loop calling anonymous sub and executing it right away to build an array of subs (which just return the loop index). It is mostly what I want, however I'm needing to use an intermediate variable ( instead of using @_, which changes on the internal function).
use warnings;
use strict;
my @funcs;
for(my $i=0;$i<3;$i++) {
sub {
my $index=shift;
$funcs[$index]=sub {$index};
}
-> ($i);
}
for (@funcs) {
print &$_()."\n";
}
#Output
0
1
2
I know I can use map to restructure this problem. But putting that aside, is there a better way to do this?
Update
Thanks to @ikegami for highlighting some important points.
Just for future views of this question, my thoughts on this:
The 'iterator' for loop has different scoping (is it a map?) than a 'c style' for loop. That cleans up the code with out needing an IIFE at all. Sweet.
Update 2
Following code shows the differences I'm seeing. Not saying one is better than the other but good to know I think. The output I'm after is 0 1 2 but the first one only repeats the last value of $i (3 after the ++ operator).
use warnings;
use strict;
my @funcs;
print "C loop direct assignment of sub\n";
for(my $i=0;$i<3;$i++) {
$funcs[$i]= sub {$i};
}
print &$_()."\n" for @funcs;
print "C loop direct assignment of sub with variable\n";
for(my $i=0;$i<3;$i++) {
my $index=$i; #assignment/copy
$funcs[$index]= sub {$index};
}
print &$_()."\n" for @funcs;
print "For loop interator\n";
@funcs=[];
for my $i (0..2) {
$funcs[$i]=sub {$i};
}
print &$_()."\n" for @funcs;
print "C loop with IIFE assignment\n";
@funcs=[];
for (my $i=0;$i<3;$i++) {
sub {
my $index=shift;
$funcs[$index]=sub {$index};
}
-> ($i);
}
print &$_()."\n" for @funcs;
Out is:
C loop direct assignment of sub
3
3
3
C loop direct assignment of sub with variable
0
1
2
For loop interator
0
1
2
C loop with IIFE assignment
0
1
2