croak "no wheels specified" unless @_;
- my @w = map { [ 1, ref eq 'ARRAY' ? @$_ : $_ ] } @_;
+ my @w = map { [ 1, ref eq 'CODE' ? $_->() : $_ ] } @_;
my $done;
####
sub odometer {
die "no wheels specified" unless @_;
my @w = map { [ $_, $_->() ] } @_;
my $done;
return sub {
if ($done) { $done=0; return }
my @cur = map { $_->[1] } @w;
for ( my $i=$#w; $i>=0; $i-- ) {
defined( $w[$i][1] = $w[$i][0]->() ) and last;
$w[$i][1] = $w[$i][0]->();
$done=1 unless $i;
}
return wantarray ? @cur : join '', map {defined()?$_:''} @cur;
};
}
####
use Test::More;
sub array_it {
my ($i,@arr) = (0,@_);
return sub { if ( $i>$#arr ) { $i=0; return } $arr[$i++] }
}
{
my $odo = odometer( array_it('foo','bar'), array_it('-'),
array_it(3..5) );
my @o;
while (defined( my $x = $odo->() )) { push @o, $x }
while (my @x = $odo->()) { push @o, \@x }
is_deeply \@o, ["foo-3", "foo-4", "foo-5", "bar-3", "bar-4",
"bar-5", ["foo","-","3"], ["foo","-","4"], ["foo","-","5"],
["bar","-","3"], ["bar","-","4"], ["bar","-","5"] ];
}
{
my $odo = odometer(
array_it(qw/ a b c /),
array_it(qw/ 1 2 /,undef,qw/ 3 4 /),
);
my @o;
while (defined( my $x = $odo->() )) { push @o, $x }
is_deeply \@o, [qw/ a1 a2 b3 b4 c1 c2 /];
@o = ();
while (defined( my $x = $odo->() )) { push @o, $x }
is_deeply \@o, [qw/ a3 a4 b1 b2 c3 c4 /];
}
done_testing;