Well, for being off the top of the head, sackyhack's idea works pretty well. The following took some research. This is another variation that benchmarks a bit faster, especially when permuting a larger set.
sub permute(@) {
@items = @_;
@set = (0..(@items - 1));
print @items,"\n";
while(@set = permutation(@set)) {
print map @items[$_], @set;
print "\n";
}
return 1;
}
sub permutation(@) {
my @r = @_;
my @tail = pop @r;
while (@r and $r[-1] > $tail[-1]) {
push @tail, pop @r;
}
if (defined(my $extra = pop @r)) {
my($place) = grep $extra < $tail[$_], 0..$#tail;
($extra, $tail[$place]) = ($tail[$place], $extra);
@r = ( @r, $extra, @tail );
} else {
return ();
}
return @r;
}
permute( qw/ a b c d e f / );
And to give credit where credit is due: this was inspired by the List:

ermutor module ... which is probably better than any of these embedded options anyway.
Have fun,
brendanc@icehouse.net