Zed_Lopez has asked for the wisdom of the Perl Monks concerning the following question:
I'm trying to use Algorithm::Loops::NestedLoops to dynamically create a set of loops (of depth to be determined at runtime) like this:
for $i (0..1) { for $j ($i+1..3) { for $k ($j+1..5) { for $l ($k+1..7) {
and so on. NestedLoops makes the $i+1 part easy, but I don't know how to generate the anonymous subroutines such that they'll have the right values for the ends of the ranges.
The obvious approach
my $depth = 4; my $loop = [[0..1]]; my $val = 3; for my $i (1..$depth-1) { push @$loop, sub {[$_+1..$val]}; $val+=2; } my $iter = NestedLoops($loop); while (my @list = $iter->()) { output(@list); } sub output { my @args = @_; print join '', @args, "\n"; }
fails because $val isn't evaluated when the subroutine is defined; it's evaluated when it's run, such that they all get its last value, 9.
Trying to be more clever by using an iterator:
fails because NestedLoops seems to end up calling the iterator more than exactly once per loop (not that I'd want to depend on the assumption it did call it exactly once per loop.)my $n = shift; sub plustwo_iter { my $val = 1; return sub { $val +=2; return $val; } } my $p = plustwo_iter(); my $loop = [[0..1], (sub {[$_+1..&$p]}) x ($n-2)]; my $iter = NestedLoops($loop); while (my @list = $iter->()) { output(@list); }
Does anyone see how this can be done with NestedLoops? (I have another solution where I build code and eval it, but I'd like to try it with NestedLoops, too.)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Building the loop arrayref for Algorithm::Loops::NestedLoops
by ikegami (Patriarch) on Sep 02, 2004 at 05:37 UTC | |
by Zed_Lopez (Chaplain) on Sep 02, 2004 at 05:52 UTC | |
|
Re: Building the loop arrayref for Algorithm::Loops::NestedLoops (stays shared)
by tye (Sage) on Sep 02, 2004 at 15:13 UTC |