Logical operators#

The boolean family — short-circuit AND, OR, defined-or; their low-precedence word-form siblings; the negations; and xor.

Operator

Reads as

Short-circuit

Returns

Precedence

!

not

n/a

normalised 1 or ""

high

&&

and

yes

left if false, else right (the operand)

high

||

or

yes

left if true, else right (the operand)

high

//

defined-or

yes

left if defined, else right (operand)

high

xor

exclusive or

no

normalised 1 or ""

very low

not

not

n/a

normalised 1 or ""

very low

and

and

yes

same as &&

very low

or

or

yes

same as ||

very low

The full conceptual treatment of these operators — what truthiness means, why && returns one of its operands, how implication and XOR fit in, the De Morgan transformations that let you simplify tangled conditions — lives in the Boolean Logic for Perl Programmers tutorial. This page is the operator-reference companion.

Short-circuit and operand return#

&& and || evaluate left-to-right and stop as soon as the result is determined.

  • A && B — if A is false, return A without evaluating B. Otherwise return B.

  • A || B — if A is true, return A without evaluating B. Otherwise return B.

The return value is the operand itself, not a normalised true/false. This is what makes Perl’s defaulting idioms work:

my $port = $config{port} || 8080;            # operand of ||, not boolean
my $name = $user_input  || "anonymous";
my $val  = $cache{$key} ||= compute($key);   # ||= sets if currently false

For comparison, !, not, and xor do normalise: they always return either 1 or the empty string "".

// — defined-or#

// short-circuits on definedness instead of truthiness:

  • A // B — if A is defined, return A. Otherwise return B.

The difference matters when 0, "", or "0" is a legitimate value rather than a stand-in for «missing»:

my $port    = $config{port} || 8080;    # 0 means "use default" — wrong
my $port    = $config{port} // 8080;    # 0 means "0", undef means "default"
my $verbose = $opt{verbose} // 0;       # 0 is a real choice

//= is the compound form:

$config{port} //= 8080;                 # set only if currently undef

xor#

The exclusive-or operator. Has only the very-low-precedence word form (there is no ^^), and unlike and/or it does not short-circuit (it cannot — both sides have to be evaluated to determine the result):

if ($admin xor $guest) { ... }          # exactly one of the two

The result is normalised — 1 or "", not an operand. For bitwise XOR on integers, see bitwise.

Symbolic vs word forms — precedence, not style#

&&, ||, ! bind tightly (rows 15–16). and, or, not bind very loosely (rows 22–24). This matters at the boundary with assignment:

my $fh = open $h, '<', $path || die "no $path: $!";
#                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
# parses as: open $h, '<', ($path || die "no $path: $!")
# — open of "either $path or the die-message". Catastrophe.

my $fh = open $h, '<', $path or die "no $path: $!";
# parses as: ($fh = open $h, '<', $path) or die "no $path: $!"
# — what you meant.

Rule of thumb:

  • Inside an expression, where you want the value to flow into a variable or another operator: use &&, ||, !, //.

  • After a statement, where you want a side-effect (die, warn, return) to fire conditionally: use or, and, not.

! and not#

Both negate. Both return the canonical 1 or "":

my $missing = ! $config{port};          # 1 if port is unset/0/""/"0"
return if not @items;                   # cleaner reading than `if !@items`

! binds high (row 5); not binds very low (row 22).

Compound forms#

Three of the logical operators have compound assignment forms:

Compound

Means

Use

&&=

$x = $x && $y

«narrow if currently true»

||=

$x = $x || $y

«default if currently false»

//=

$x = $x // $y

«default if currently undef»

$cache{$k} ||= compute($k);             # lazy populate
$cfg{port} //= 8080;                    # default that respects 0
$check     &&= validate($check);        # only if currently truthy

Tutorial cross-reference#

The conceptual underpinnings of this page are covered in the boolean-logic tutorial:

See also#

  • Bitwise — the same boolean operators applied to integer bits in parallel.

  • Ternary?:, logical selection as an expression.

  • Numeric comparison and string comparison — produce the boolean inputs that the operators on this page combine.

  • Error variables$! and $@ are the values you typically put on the right-hand side of the or die idiom that this page’s word-form operators were made for.