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