Section 4.16. Low-Precedence Operators


4.16. Low-Precedence Operators

Don't mix high- and low-precedence booleans.

Perl's low-precedence logical not reads much better than its corresponding high-precedence ! operator. So it's tempting to write:

     next CLIENT if not $finished;    # Much nicer than: if !$finished

However, the extremely low precedence of not can lead to problems if that condition is later extended:

     next CLIENT if not $finished || $result < $MIN_ACCEPTABLE;

It's likely that at least some readers of your code will mistake the behaviour of that statement and assume that it's equivalent to:

     next CLIENT if (not $finished) || $result < $MIN_ACCEPTABLE;

It's not. It actually means:

     next CLIENT if not( $finished || $result < $MIN_ACCEPTABLE );

Even if the choice of || was deliberate, and implements the desired test correctly, there is nothing in the code to indicate that the mixing of precedence was intentional. So, while the novice reader is left to wonder about the meaning of the expression, the more experienced reader is left to wonder about its correctness.

Replacing the || with an or would solve the precedence problem (if indeed there were one), since or is even lower precedence than not:

     next CLIENT if not $finished or $result < $MIN_ACCEPTABLE;

And then adding a pair of parentheses would explicitly indicate whether the intention was:

     next CLIENT if not($finished or $result < $MIN_ACCEPTABLE);

or:

     next CLIENT if not($finished) or $result < $MIN_ACCEPTABLE;

On the other hand, the high-precedence boolean operators don't seem to invoke the same levels of fear, uncertainty, or doubt, probably because they're used much more frequently. It's safer and more comprehensible to use only high-precedence booleans in conditional expressions:

      next CLIENT if !$finished || $result < $MIN_ACCEPTABLE;

and then use parentheses when you need to vary precedence:

      next CLIENT if !( $finished || $result < $MIN_ACCEPTABLE);

To maximize the comprehensibility of conditional tests, avoid and and not completely, and reserve low-precedence or for specifying "fallback positions" on fallible builtins:

      open my $source, '<', $source_file         or croak "Couldn't access source code: $OS_ERROR";

(but see also "Builtin Failures" in Chapter 13).



Perl Best Practices
Perl Best Practices
ISBN: 0596001738
EAN: 2147483647
Year: 2004
Pages: 350
Authors: Damian Conway

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net