use warnings; use strict; sub Iterator (&) { return $_[0] } # syntactic sugar per hop sub cyclic_array_iter { my @array = @_; # copy of array to iterate my $i = $[; # iterated array index return Iterator { return } unless @array; # maybe die here? return Iterator { if (@_) { $i = $_[0]; $i = $[ if $i > $#array or $i < $[; return; } my $element = $array[$i++]; $i = $[ if $i > $#array; return $element; }; } use Test::More 'no_plan'; sub play { return "$_[0] likes to play"; } sub eat { return "$_[0] likes to eat"; } sub nap { return "$_[0] likes to nap"; } my @people = qw(tom harry diana nick sally henry); my @activities = (\&play, \&eat, \&nap); my $person = cyclic_array_iter(@people); my $activity = cyclic_array_iter(@activities); for my $name (@people) { is($person->(), $name, "person: $name"); } is($person->(), 'tom', 'wrap: person: tom'); is($person->(), 'harry', 'person: harry'); $person->(0); is($person->(), 'tom', 'after re-indexing: person: tom'); is($person->(), 'harry', 'person: harry'); $person->(-1); is($person->(), 'tom', 'after bad index (-1): person: tom'); is($person->(), 'harry', 'person: harry'); $person->(1 + $#people); is($person->(), 'tom', 'after bad index (1 beyond): person: tom'); is($person->(), 'harry', 'person: harry'); $person->(99_999); is($person->(), 'tom', 'after bad index (big): person: tom'); is($activity->()->($person->()), 'harry likes to play', 'harry,play'); $activity->()->($person->()); is($activity->()->($person->()), 'nick likes to nap', 'nick,nap'); is($activity->()->($person->()), 'sally likes to play', 'sally,play'); is($activity->()->($person->()), 'henry likes to eat', 'henry,eat'); is($activity->()->($person->()), 'tom likes to nap', 'tom,nap'); #### >perl cyclic_array_iter_1.pl ok 1 - person: tom ok 2 - person: harry ok 3 - person: diana ok 4 - person: nick ok 5 - person: sally ok 6 - person: henry ok 7 - wrap: person: tom ok 8 - person: harry ok 9 - after re-indexing: person: tom ok 10 - person: harry ok 11 - after bad index (-1): person: tom ok 12 - person: harry ok 13 - after bad index (1 beyond): person: tom ok 14 - person: harry ok 15 - after bad index (big): person: tom ok 16 - harry,play ok 17 - nick,nap ok 18 - sally,play ok 19 - henry,eat ok 20 - tom,nap 1..20