EXP04-PL. Do not mix the early-precedence logical operators with late-precedence logical operators
Perl provides three logical operators: && , || , and ! , and they have the same meaning as in C.
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 recommends avoiding the use of not and and entirely and using or only in control-flow operations, as a failure mode [ Conway 2005 ]:
print $filehandle $data or croak("Can't write to file: $!");
Noncompliant Code Example
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.
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.
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:
if (not (-f $file || -w $file)) {
when the maintainer really wanted:
if ((not -f $file) || -w $file) {
Compliant Solution
This compliant solution uses the ! operator in conjunction with the || operator. This code has the desired behavior of determining if a file either does not exist or does exist but is overwritable.
if (! -f $file || -w $file) {
Compliant Solution
This compliant solution uses the early-precedence operators consistently. Again, the code works as expected.
if (not -f $file or -w $file) {
Risk Assessment
Mixing early-precedence operators with late-precedence operators can produce code with unexpected behavior.
| Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
| EXP04-PL | Low | Unlikely | Low | P3 | L3 |
Automated Detection
| Tool | Diagnostic |
| Perl::Critic | ValuesAndExpressions::ProhibitMixedBooleanOperators |
Bibliography
| [ CPAN ] | Elliot Shank, Perl-Critic-1.116 ProhibitMixedBooleanOperators |
| [ Conway 2005 ] | "Low-Precedence Operators," p. 70 |
| [ Wall 2011 ] | perlop |


