Perl provides three logical operators: &&
, ||
, and !
, and they have the same meaning as in C.
Perl also provides three alternate 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 will often lead to confusing, counterintuitive behavior. Therefore, every Perl expression should use either the early-precedence operators or the late-precedence ones, never both.
[Conway 2005] recommends avoiding the use of not
and and
entirely, and only using or
in control-flow operations, as a failure mode:
print $filehandle $data or croak("Can't write to file: $!");
Noncompliant Code Example
This noncompliant code example checks a file to see if it is suitable 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. This code will instead behave like the following:
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 |
P1 |
L3 |
Automated Detection
Tool |
Diagnostic |
---|---|
Perl::Critic |
ValuesAndExpressions::ProhibitMixedBooleanOperators |
Bibliography
[CPAN]. Elliot Shank, Perl-Critic-1.116. ProhibitMixedBooleanOperators.
[Conway 2005], pg 70
[Wall 2011] perlop
EXP11-C. Do not apply operators expecting one type to data of an incompatible type 03. Expressions (EXP) EXP13-C. Treat relational and equality operators as if they were nonassociative