# Ternary operator One operator, three operands. Logical selection as an *expression* — the result has a value, can be assigned, returned, passed as an argument. ## Form ```default COND ? THEN : ELSE ``` If `COND` is true, the value is `THEN`; otherwise it is `ELSE`. Only the chosen branch is evaluated: ```perl my $label = $count == 1 ? "1 item" : "$count items"; return $ok ? \%result : undef; my $abs = $x < 0 ? -$x : $x; ``` ## It is an expression, not a statement The most common reason to reach for `?:` instead of `if`/`else` is that you want a *value* — to assign, to return, to put inside another expression: ```perl # verbose my $kind; if ($n == 1) { $kind = 'singular' } else { $kind = 'plural' } # idiomatic my $kind = $n == 1 ? 'singular' : 'plural'; ``` ## Chaining (right-associative) `A ? B : C ? D : E` parses as `A ? B : (C ? D : E)` — the chain descends through the false branch: ```perl my $sign = $x < 0 ? '-' : $x > 0 ? '+' : '0'; ``` The columnar layout makes the chain readable. Past two or three levels, switch to `if`/`elsif`/`else` — the chain stops being clearer than the alternative. ## Ternary as lvalue Both branches must be lvalues, and the chosen branch is the lvalue you assign to: ```perl my ($pos, $neg) = (0, 0); ($x > 0 ? $pos : $neg) = $x; # assigns to $pos or $neg # Common case: pick a buffer to append to ($verbose ? $log : $debug) .= "$msg\n"; ``` This pattern is rare in modern code — an explicit `if` with two straightforward assignments reads better. Worth knowing for when you encounter it. ## What you don’t write `?:` is *not* a statement separator. These are wrong: ```perl $x ? do_a() : do_b(); # OK: do_a/do_b have side-effects, # but the value is discarded $x > 0 ? print "yes\n" : print "no\n"; # WORKS, but reads strangely ``` When the goal is a side-effect (rather than a value), use `if`/`else` or the postfix `if`/`unless`: ```perl $x > 0 ? do_yes() : do_no(); # value-return phrasing do_yes() if $x > 0; # side-effect phrasing do_no() unless $x > 0; ``` ## With short-circuit logical operators `?:` interacts with `&&`, `||`, `//` in ways that can confuse the eye. Almost always parenthesise: ```perl my $x = $a || $b ? $c : $d; # parses as ($a || $b) ? $c : $d # because || binds tighter than ?: my $x = $a || ($b ? $c : $d); # if you meant the other thing, # parenthesise ``` ## Precedence `?:` sits at row 18 — looser than the boolean operators (`&&`/`||`/`//`), tighter than assignment. This is why `my $x = COND ? A : B` works without parens around the right-hand side. ## See also - [Logical](logical.md) — short-circuit `&&` and `||`, the alternative-without-`if` family. - [Boolean Logic — Operators](../../../tutorial/boolean-logic/operators.md) — `?:` in the context of all the boolean operators. - [Assignment](assignment.md) — `?:` as lvalue.