# Bruterate.pm brute force list iterator generator 03jul09waw package Bruterate; { # begin Bruterate private package closure use warnings FATAL => 'all'; # use warnings; use strict; use Exporter; our @ISA = qw(Exporter); our $VERSION = '0.1.0'; our @EXPORT = (); # default exports our @EXPORT_OK = qw(bruterate); # optional exports sub Iterator (&) { return $_[0] } # syntactic sugar per hop # return iterator that will iterate over all elements of a set # of referenced arrays. referenced arrays that are empty are # ignored. elements in array referenced by right-most argument # in call to function are iterated most rapidly, elements in # array referenced by left-most argument least rapidly. sub bruterate { # ignore any referenced arrays that are empty. my @ar_non_empty = grep @$_ > 0, @_; # no referenced non-empty arrays to iterate over. return Iterator { return } unless @ar_non_empty; # at least one referenced non-empty array to iterate over. my @items = @{ shift @ar_non_empty }; my $item = $[; # is this the rightmost referenced non-empty array to be iterated? @ar_non_empty == 0 and return Iterator { $item = $[, return if $item > $#items; return [ $items[$item++] ]; }; # there are more referenced arrays (to the right) to iterate. my $cr_get_rightward_items = bruterate(@ar_non_empty); return Iterator { my $ar_rightward = $cr_get_rightward_items->(); return [ $items[$item], @$ar_rightward ] if $ar_rightward; ++$item; $item = $[, return if $item > $#items; return [ $items[$item], @{ $cr_get_rightward_items->() } ]; }; } # end sub bruterate() } # end Bruterate private package closure 1;