You know (leaving the in-place assignment issue aside), it occured to me (duh) that this is a general purpose but faster rephrasing of the Schwartzian Transform:
sub sxsorta (&;) {
my $sort_key = shift;
my @rank = map &$sort_key, @_;
@_[ sort { $rank[$a] cmp $rank[$b] } 0 .. $#_ ];
}
sub sxsortn (&;) {
my $sort_key = shift;
my @rank = map &$sort_key, @_;
@_[ sort { $rank[$a] <=> $rank[$b] } 0 .. $#_ ];
}
The gains over the regular ST comes from the fact that it doesn't create hundreds of tiny anonymous arrays, and that the sort callback is slightly faster because it only has to do an array lookup but no dereferencing.
The drawback is that with a lexically scoped (as it should be) @rank, there's no way to pass a userspecified callback to the routines without inflicting a massive performance hit. To do more complex sorts, one therefor has to separately spell this idiom out in their own code.
Makeshifts last the longest.