...
Perl also provides three alternative logical operators: and, or, and not. They have the same meanings as &&, ||, and !. They have much lower binding precedence, which makes them useful for control flow [Wall 2011]. They are called the late-precedence logical operators, whereas &&, ||, and ! are called the early-precedence logical operators.
It is possible to mix the early-precedence logical operators with the late-precedence logical operators, but this mixture of precedence often leads to confusing, counterintuitive behavior. Therefore, every Perl expression should use either the early-precedence operators or the late-precedence ones, never both.
[Damian Conway 2005] recommends avoiding the use of not and and entirely and using or only in control-flow operations, as a failure mode [Conway 2005]:
| Code Block | ||
|---|---|---|
| ||
print $filehandle $data or croak("Can't write to file: $!");
|
...
This noncompliant code example checks a file for suitability as an output file. It does this by checking to see that the file does not exist.
| Code Block | ||
|---|---|---|
| ||
if (not -f $file) {
|
This code is perfectly fine. However, it is later amended to also work if the file does exist but can be overwritten.
| Code Block | ||||
|---|---|---|---|---|
| ||||
if (not -f $file || -w $file) {
|
This code will not behave as expected because the binding rules are lower for the not operator than for the ! operator. Instead, this code behaves as follows:
| Code Block | ||
|---|---|---|
| ||
if (not (-f $file || -w $file)) {
|
when the maintainer really wanted:
| Code Block | ||
|---|---|---|
| ||
if ((not -f $file) || -w $file) {
|
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
if (! -f $file || -w $file) {
|
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
if (not -f $file or -w $file) {
|
...
Tool | Diagnostic |
|---|---|
Perl::Critic | ValuesAndExpressions::ProhibitMixedBooleanOperators |
Bibliography
...
...