in reply to iterator w/ wantarray()
Put print statements into your subs (Basic debugging checklist), and you'll see that $value will never change, since all that that sub is returning is $from+$step every time it's called. You have to move the my $value=$from; outside of that sub so that it will close over it (closures).
By the way, Want seems to mess with the internals, and it has several open bugs in regards to segfaults. The typical approach to iterators is to have them return undef at the end of the sequence, and you can also overload the <> operator, as I did in Algorithm::Odometer::Tiny (note that overloading <> in list context only works on Perl 5.18 and up). By the way, the book Higher-Order Perl is an excellent read in regards to iterators and all the things you can do with them.
use warnings; use strict; use Want 'howmany'; sub multi_iterator { my ($iterator) = @_; return sub { my $context = wantarray(); print "multi_iterator called, <$context>\n"; return unless defined $context; return $iterator->() unless $context; return map { $iterator->() } 1 .. howmany(); }; } sub counter { my ($from, $to, $step) = @_; $step ||= 1; my $value = $from; return sub { print STDERR "counter called, $from / $to / $step / $value\n"; return if $value > $to; my $v = $value; $value += $step; return $v; }; } my $counter = counter(1, 10, 3); my $iterator = multi_iterator($counter); my ($un, $deux) = $iterator->(); my $trois = $iterator->(); print "Hack-27 ", $un, ",", $deux, ",", $trois, "\n"; __END__ multi_iterator called, <1> counter called, 1 / 10 / 3 / 1 counter called, 1 / 10 / 3 / 4 multi_iterator called, <> counter called, 1 / 10 / 3 / 7 Hack-27 1,4,7
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: iterator w/ wantarray()
by cmic (Acolyte) on Apr 25, 2020 at 21:00 UTC | |
by tobyink (Canon) on Apr 27, 2020 at 07:09 UTC |