B.11
Conditionals and Logical Operators
This section covers conditional statements and logical
operators.
B.11.1
true and false
In a conditional test, an expression evaluates to
true
or false, and
based on the result, a statement or block may or may not be executed.
A scalar value can be true or
false in a conditional. A string is
false if it's the empty string (represented
as "" or ''). A string is
true if it's not the empty string.
Similarly, an array or a hash is false if empty,
and true if nonempty.
A number is false if it's 0; a number is
true if it's not 0.
Most things you evaluate in Perl return some value (such as a number
from an arithmetic expression or an array returned from a
subroutine), so you can use most things in Perl in conditional tests.
Sometimes you may get an
undefined
value, for instance if you try to add a number to a variable that has
not been assigned a value. Then things might fail to work as
expected. For instance:
use strict;
use warnings;
my $a;
my $b;
$b = $a + 2;
produces the warning output:
Use of uninitialized value in addition (+) at - line 5.
You can test for defined and undefined values with the Perl function
defined.
B.11.2
Logical Operators
There are four logical operators:
- not
- and
- or
- xor
not turns true values into
false and false values into
true. Its use is best illustrated in code:
if(not $done) {...}
This executes the code only if $done is
false.
and is a binary operator that returns
true if both its operands are
true. If one or both of the operands are
false, the operator returns
false:
1 and 1 returns true
'a' and '' returns false
'' and 0 returns false
or is a binary operator that returns
true if one or both of the operands are
true. If both operands are
false, it returns false:
1 or 1 returns true
'a' or '' returns true
'' or 0 returns false
xor, or exclusive-OR,
returns true
if one operand is true and the other operand is
false; xor returns
false if both operands are true
or if both operands are false:
1 xor 0 returns true
0 xor 1 returns true
1 xor 1 returns false
0 xor 0 returns false
There are also variants on most of these:
- ! for not
- && for and
- || for or
These have different precedence but otherwise behave the same. Some
older versions of Perl may only have:
- !
- ||
- &&
instead of not or and.
B.11.3
Using Logical Operators for Control Flow
A quick and popular way to take an action
depending on the results of a previous action is to
chain the statements together with
logical operators. For instance, it's common in Perl programs
to see the following statement to
open
a file:
open(FH, $filename) or die "Cannot open file $filename: $!";
The use of or in this statement shows
another important thing about the binary logical operators: they
evaluate their arguments left to
right. In this case, if the open succeeds, the or
operator never bothers to check the value of the second operand
(die, which exits the program with the message in
the string, plus additional messages if $! is
included). The or never bothers, because if one
operand is true, the or is
true, so it doesn't need to check the second
operand. However, if the open fails, the or needs
to check that the second operand is true or
false, so it goes ahead and executes the
die statement.
You can use the and statement similarly to test
the second operand only if the first operand succeeds.
xor doesn't work for control flow, since
both its arguments have to be evaluated each time.
I haven't used this chaining of logical operators much;
I've used if statements instead. This is because
I often find that I want to add more statements following a test, and
it's easier if the original is written as an
if statement with a block, and harder if the
original is written as a logical operator.
B.11.4
The if Statement
Conditional tests are commonly found in if
statements and in their variants and loops. Here's an example
of an if statement:
if (open (FH, $filename) {
print "Hurray, I opened the file.";
}
The if statement is followed by a conditional
expression enclosed in parentheses, which is followed by a block
enclosed in curly braces { }. When the conditional
expression evaluates as true, the statements in
the block are executed.
The if statement may optionally be followed by an
else, which is executed when the
conditional evaluates to false:
if ( open(FH, $filename) {
print "Hurray, I opened the file.";
} else {
print "Rats. The file did not open.";
}
The if statement may also optionally include any
number of elsif clauses, which check additional
conditional statements if none of the preceding conditional
statements are true:
if ( open(FH, $file1) {
print "Hurray, I opened file 1.";
} elsif ( open(FH, $file2) {
print "Hurray, I opened file 2.";
} elsif ( open(FH, $file3) {
print "Hurray, I opened file 3.";
} else {
print "None of the dadblasted files would open.";
}
In the preceding example, if file
1 opened successfully, the if
statement doesn't try to open additional files.
There is also an unless statement, which is the same as an
if statement with the conditional negated. So
these two statements are equivalent:
unless ( open(FH, $filename) {
print "Rats. The file did not open.";
}
if ( not open(FH, $filename) {
print "Rats. The file did not open.";
}