#! perl -slw use strict; sub nForX(&@) { my $code = shift; my $n = shift; return $code->( @_ ) unless $n; for my $i ( @{ shift() } ) { &nForX( $code, $n-1, @_, $i ); } } my %stuff = ( X => [ qw[ X1 X2 X3 ] ], Y => [ qw[ Y1 Y2 Y3 ] ], Z => [ qw[ Z1 Z2 Z3 ] ], ); print "@ARGV"; my $pat = $ARGV[0] // 'X::Y'; my @keys = split '::', $pat; nForX { print "@_"; } scalar @keys, @stuff{ @keys }; __END__ C:\test>junk X1 Y1 X1 Y2 X1 Y3 X2 Y1 X2 Y2 X2 Y3 X3 Y1 X3 Y2 X3 Y3 C:\test>junk X::Z X::Z X1 Z1 X1 Z2 X1 Z3 X2 Z1 X2 Z2 X2 Z3 X3 Z1 X3 Z2 X3 Z3 C:\test>junk X::Y::Z X::Y::Z X1 Y1 Z1 X1 Y1 Z2 X1 Y1 Z3 X1 Y2 Z1 X1 Y2 Z2 X1 Y2 Z3 X1 Y3 Z1 X1 Y3 Z2 X1 Y3 Z3 X2 Y1 Z1 X2 Y1 Z2 X2 Y1 Z3 X2 Y2 Z1 X2 Y2 Z2 X2 Y2 Z3 X2 Y3 Z1 X2 Y3 Z2 X2 Y3 Z3 X3 Y1 Z1 X3 Y1 Z2 X3 Y1 Z3 X3 Y2 Z1 X3 Y2 Z2 X3 Y2 Z3 X3 Y3 Z1 X3 Y3 Z2 X3 Y3 Z3