![]() |
|
Perl-Sensitive Sunglasses | |
PerlMonks |
Perl Idioms Explained - && and || "Short Circuit" operatorsby davido (Cardinal) |
on Oct 22, 2003 at 20:28 UTC ( [id://301355]=perlmeditation: print w/replies, xml ) | Need Help?? |
Inspired by some goings-on yesterday in the CB I realized that a discussion of the many uses of the && and || operators might be in order. Camel (Programming Perl, O'Reilly) calls them "C-style Logical (Short Circuit) Operators." So can something so blatently borrowed from C be considered an integral Perl idiom? Definately. Here's why, and why they're an important part of the Perl toolbelt.
C-style?
Why "Short Circuit?"
Camel II tells us that the term "Short-Circuit" refers to the fact that they "determine the truth of the statement by evaluating the fewest number of operands possible." So essentially these operators stop the chain of evaluation of an expression as early as possible. That is another key to their value.
I hope some readers find this discussion helpful.
Why "Logical?"
What do they do?
The above table also lists && and ||'s siblings: 'and' and 'or'. The latter two work the same as the former two, except with a lower precedence, so as to reduce the need for parenthesis. More on that later.
A closer look at && logic and short-circuiting: Here is a set of simple examples that illustrate what these operators are doing:
In the above example you can see short-circuiting and logic both in action. "Truth" is only printed in the first example, because that is the only example where $this and $that were true at the time of evaluation. The rest of the examples showed how short-circuiting affected whether or not the second expression ($that) ever got evaluated. You can see if it gets evaluated by virtue of the ++ operator: If it got incremented, it got evaluated. ||'s version of logic and short-circuiting: The following examples express in fairly simple terms what || does:
So to use a catchy phrase, && "falls through" if the first expression is true, and returns truth if both are true.
So what about the idioms?
That's one you see all over the place. In a moment I'll mention why "open(...) or die ..." is better than "open(...) || die ...". The great thing about these operators is that they "read well". They do exactly what they say: "open or die", for example. Here's another common idiom that uses && to provide a C-like "switch" statement (Ok, now I promise not to mention C anymore):
(Credit to perlsyn for the bulk of that example.) The preceeding example may look a little funky. How does it make sense to say "if this and do that"? Remember that "do" returns the value of the last expression evaluated inside it. So basically the preceeding example says "If this and that." But the truthfulness of the second expression isn't important anyway. What we're doing is evaluating the truthfulness of the first expression to determine whether or not to fall through to evaluate the second expression. So in the preceeding example, "$_ =~ /^xyz/" is true, so everything inside the do{ ... } expression gets evaluated, or executed. This is one of the ways to implement switch (hashtables can be more efficient though). Now you know one reason why Perl 5 doesn't have a switch statement (though there is a Switch module if you really need switch, and Perl 6 will have it). You are free to chain these operators together as well. You could, for example, say:
or even...
And now for the super-cool idiom that reminded me that I wanted to write this node in the first place:
What is going on here? Remember that "cmp" and "<=>" evaluate to "zero" (false) if the left hand side and the right hand side are equal, and "false" will make '||' fall through to the next level. We're sorting a list case-insensitively, but if there is both an upper-case and lower-case string that, when evaluated case-insensitively, would evaluate to being equal, the || will fall through to the second expression, which evaluates case-SENsitively. In other words: (qw/b c a C D E e f/) would sort as: (qw/a b C c D E e f/) (assuming you're on an ASCII system). This idiom can be wielded in an even more powerful way. Consider, for example, a multi-dimensional entity where you want to sort complexly (is that a word?):
In that example, you're going to sort by name first, and whenever two names are equal, fall through to subsort by age.
Precedence
Just think of "and" and "or" as being the same as && and ||, but so low on the precedence chart that parenthesis are usually unnecessary to keep the things on the left or on the right properly grouped. It is almost always considered better to use "or" instead of "||" when you work with open. Ok, that's all I have to say. Thanks for staying awake through this longwinded node! Update: My thanks to hardburn, Abigail-II, tye, Enlil, diotalevi, demerphq and a few others for providing comments that helped me to refine this node a bit.
Additional Reading:
Dave "If I had my life to live over again, I'd be a plumber." -- Albert Einstein
Back to
Meditations
|
|