Another alternative to looping is to use the glob built-in.
johngg@shiraz:~/perl/Monks$ perl -Mstrict -Mwarnings -E '
my @arr1 = qw{ 1 2 3 };
my @arr2 = q{a} .. q{g};
my @arr3 = qw{ I II III };
my $globStr
= qq{{@{ [ join q{,}, @arr1 ] }}}
. qq{{@{ [ join q{,}, @arr2 ] }}}
. qq{{@{ [ join q{,}, @arr3 ] }}};
say $globStr;
say for glob $globStr;'
{1,2,3}{a,b,c,d,e,f,g}{I,II,III}
1aI
1aII
1aIII
1bI
1bII
1bIII
1cI
1cII
1cIII
1dI
1dII
1dIII
1eI
1eII
1eIII
1fI
1fII
1fIII
1gI
1gII
1gIII
2aI
2aII
2aIII
2bI
2bII
2bIII
2cI
2cII
2cIII
2dI
2dII
2dIII
2eI
2eII
2eIII
2fI
2fII
2fIII
2gI
2gII
2gIII
3aI
3aII
3aIII
3bI
3bII
3bIII
3cI
3cII
3cIII
3dI
3dII
3dIII
3eI
3eII
3eIII
3fI
3fII
3fIII
3gI
3gII
3gIII
I hope this is of interest.
Update : AnomalousMonk quite rightly points out that I'm the idiot who didn't read the question properly, a failing that has dogged me since O- and A-levels at school :-(
Getting the left-hand value to circulate the fastest and inserting the required commas involves some jiggery-pokery to insert marker text into a re-ordered $globStr and a split, reverse and join in a map for each string generated by glob. Probably more trouble than it's worth.
johngg@shiraz:~/perl/Monks$ perl -Mstrict -Mwarnings -E '
my @arr1 = qw{ 1 2 3 };
my @arr2 = q{a} .. q{g};
my @arr3 = qw{ I II III };
my $globStr
= qq{{@{ [ join q{,}, @arr3 ] }}}
. q{__}
. qq{{@{ [ join q{,}, @arr2 ] }}}
. q{__}
. qq{{@{ [ join q{,}, @arr1 ] }}};
say $globStr;
say for
map { join q{,}, reverse split m{__} }
glob $globStr;'
{I,II,III}__{a,b,c,d,e,f,g}__{1,2,3}
1,a,I
2,a,I
3,a,I
1,b,I
2,b,I
3,b,I
1,c,I
2,c,I
3,c,I
1,d,I
2,d,I
3,d,I
1,e,I
2,e,I
3,e,I
1,f,I
2,f,I
3,f,I
1,g,I
2,g,I
3,g,I
1,a,II
2,a,II
3,a,II
1,b,II
2,b,II
3,b,II
1,c,II
2,c,II
3,c,II
1,d,II
2,d,II
3,d,II
1,e,II
2,e,II
3,e,II
1,f,II
2,f,II
3,f,II
1,g,II
2,g,II
3,g,II
1,a,III
2,a,III
3,a,III
1,b,III
2,b,III
3,b,III
1,c,III
2,c,III
3,c,III
1,d,III
2,d,III
3,d,III
1,e,III
2,e,III
3,e,III
1,f,III
2,f,III
3,f,III
1,g,III
2,g,III
3,g,III