# we pass the sub the actual values to compare foreach my $id ( sort { mysort($direction,$hash{$a}{$orderby},$hash{$b}{$orderby}) } keys %hash ) { print "$id - $hash{$id}{$orderby}\n"; } # end-foreach sub mysort { my ($direction, $_a, $_b) = @_; # generalized, simplified comparison my $result = $_a <=> $_b || $_a cmp $_b; # default to ascending, but if the dir is 'DESC', we # return the *opposite* answer return ($direction eq 'DESC') ? -($result) : $result; }