#!/usr/env/perl use strict; use warnings; my $q = (shift or 129); my @x = ( 'A' x $q, 'B' x $q ); my $glob = '{' . join(',', @x) . '}'; while (my $g = glob($glob)) { print "$g\n"; # no output if $q > 129 } ##### returns nothing with 129 #### #### my @x = (1..10); my @y = qw(one two three four five six seven eight nine ten); my @z = qw(Amy Bob Cal Deb Eck Fay Gin Hob Ian Jan); my @xyz = (\@x, \@y, \@z); my $glob = join( ',', map { '{' . join( ',', @$_ ) . '}' } @xyz ); #### sub make_combo_iter { my $array_ref = shift; # last index of top level my $size = scalar( @{$array_ref} ); # create array of last indices my @array_limits; for my $i (0..$size-1) { $array_limits[$i] = scalar( @{$array_ref->[$i]} ) - 1; } # one counter for each sub-array my @array_counter = (0) x $size; my $done = 0; my $iter = sub { if ($done) { $done = 0; return undef; } my @next_combo; # compute @next_combo for my $i (0..$size-1) { push @next_combo, $array_ref->[$i][$array_counter[$i]]; } # increment counters, set $done if the last one rolls over my $rollover = 0; for my $c (0..$size-1) { if (++$array_counter[$c] > $array_limits[$c]) { $array_counter[$c] = 0; # reset $rollover = 1; # carry } else { $rollover = 0; # no carry last; # no more increments } } # if the last array rolled over, set the done flag if ( $rollover ) { $done = 1; } return \@next_combo; }; # anonymous iterator sub return $iter; } # make_combo_iter