in reply to Multiple Sort on selected column
I happen to like to write separate subroutines for sorting, especially if I am going to do several different sorts that are need to be identical ... in that case, it’s only one thing to maintain and nothing to keep in-sync.
Multi-field comparison functions are made very easy by the <=> operator, (edit, see below) and ‘cmp’, both of which (as per perldoc perlop), “returns -1, 0, or 1 depending on whether the left argument is numerically or string-wise less than, equal to, or greater than the right argument.” Combine this either of these with ||, which “performs a short-circuit logical-OR operation. (“Short-circuit,” in the case of logical-OR, mans that if the left-hand part is determined to be “True,” evaluation of the right-hand part is omitted since “True OR anything == True.”) Since any non-zero value is True, a series of <=> comparisons can be chained using || to produce the intended result. It is clear at a glance what the code is doing.
{ $$a{'last_name'} cmp $$b{'last_name'} || $$a{'first_name'} cmp $$b{'first_name'} // evaluated only if 'last_ +name's are equal }
Very Important Edit! It has very graciously been pointed out to me that the <=> operator is numeric whereas the cmp operator is the string operator that, in the foregoing example, I of course should have used. (The above example has been edited to include it.) One of the serious “gotchas” of Perl, which I confess that I have never quite understood, is that there are two entirely-separate sets of comparison and relational operators: one for strings, and another for non-strings. The original code, which used the <=> operator, would have compiled and ran, but would not have produced the intended result. Thank-you to whoever-it-was for pointing this error out to me. It is a critical error indeed. But, with the change as noted, the original premise once again holds. (We can defer the question of “why does Perl do this” ... indefinitely.)