jweed provided an accurate code example. It relies on a combination of two great little tricks.
The first is the logical short circuit "or".
The way 'or' works ('||' also) is to evaluate the first argument first. If it evaluates to truth, there's no need to go further. Truth, in a Perl sense, is anything that isn't false or undef. If the first argument (the left hand side of the 'or' operator) evaluates to false, then the right hand side must be evaluated for truth or falseness. Think of it as "try this, and if it doesn't work, try that".
The logical short circuit "or" operator can be chained; this, or that, or some other thing, or yet another..., and so on. Always, once truth is found (as far to the left-hand-side of the chain as possible), the remainder of the chain is not evaluated.
That leads to the next neat little trick.
The comparison operator (<=>, and cmp) returns -1 or 1 for less-than and greater-than comparison results, but returns zero for equality. Zero is false, as far as Perl is concerned. So what happens if you chain something together like this?...
$a <=> $b or
$c <=> $d or
$e <=> $f
Just read it through: Compare $a and $b. If they're not equal, return a value of -1 or 1. But if they're equal, then the first comparison returns false, and the 'or' short-circuit operator realizes it must evaluate the right-hand side to find a non-false result. $c and $d are compared. If they're different, a -1 or 1 is returned. If they're equal, zero is returned and the next 'or' forces evaluation of the next expression.
With this idiom you can chain any number of complex comparisons together in a sort routine. It's really kind of nifty. Actually, I was tinkering with this idiom about three weeks ago in the context of dynamically-specified sort criteria, and it eventually led me to this meditation (which you may find demonstrative of the techniques involved in complex sorting): Fun with complex sorting on arbitrary criteria list.
Enjoy!
|