# 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/boolean-logic/index.md) 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: ```perl 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“: ```perl 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: ```perl $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): ```perl 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](bitwise.md). ## 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: ```perl 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 `""`: ```perl 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“ | ```perl $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: - [Truthiness](../../../tutorial/boolean-logic/truthiness.md) — what Perl considers false. - [Operators](../../../tutorial/boolean-logic/operators.md) — the operand-return rule, the precedence reasoning, and the ternary `?:` (which lives in [its own page](ternary.md) on this reference). - [Truth tables](../../../tutorial/boolean-logic/truth-tables.md) — all sixteen binary functions and how to spell each in Perl. - [De Morgan](../../../tutorial/boolean-logic/de-morgan.md) — reducing convoluted `unless` to clean `if`. - [Functional completeness](../../../tutorial/boolean-logic/functional-completeness.md) — NAND/NOR. ## See also - [Bitwise](bitwise.md) — the same boolean operators applied to integer bits in parallel. - [Ternary](ternary.md) — `?:`, logical selection as an expression. - [Numeric comparison](numeric-comparison.md) and [string comparison](string-comparison.md) — produce the boolean inputs that the operators on this page combine. - [Error variables](../perlvar/error.md) — `$!` 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.