sub alternate { my $iter = shift; my $loop = shift; # main loop callback my @conds; while (@_ > 0) { # sub to get value, sub to call if value changed push @conds, [ shift, shift ]; } my @memory; return unless $iter->(); # starting values @memory = map { $_->[0]->() } @conds; do { $loop->(); while (my ($idx, $cond) = each @conds) { my $new = $cond->[0]->(); next if $memory[$idx] eq $new; $cond->[1]->(); # callback $memory[$idx] = $new; # reset subsequent values $memory[$_] = $conds[$_][0]->() for ($idx + 1 .. $#conds); last; } } while ($iter->()); } my $gen = make_generator(\my ($day, $type, $word)); alternate( $gen, sub { print "$word, " }, sub { $day }, sub { print "\n$day" }, sub { $type }, sub { print "" } );