A.12 Conditionals and Logical Operators

This section covers conditional statements and logical operators.

A.12.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 example, if you try to add a number to a variable that has not been assigned a value. Things might then fail to work as expected. For instance, the following:

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.

A.12.2 Logical Operators

There are four logical operators:


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.

A.12.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, because both its arguments have to be evaluated each time.

I haven't used this chaining of logical operators much; instead, I've used if statements. 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 it's harder if the original is written as a logical operator.

A.12.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.";