Elvis operator
In computer programming, the binary operator ?:
colloquially referred to as the Elvis operator due to its resemblance to an emoticon,[1][2] is a shorthand binary variant of the ternary conditional operator in languages such as PHP[3][4] and Groovy.[5] It is used by several other languages that use the ? :
operator, which is the most common ternary operator.[6]
Binary ?:
, used as an operator with two arguments around it and no characters in between, is used to obtain a value that is specified in the second argument if the first argument is false, and to return the value of the first argument otherwise.
That is, the following assignments are almost equivalent:
a = b ?: c a = b ? b : c
In the previous sentence the word "almost" is there because in the first case b
is evaluated only once while in the latter one it is twice.
In other words, an Elvis operation can be understood to represent a ?:
ternary operation with the second argument omitted and assumed to equal the first.
For example,
var = foo ?: bar
contains the expression
foo ?: bar
which evaluates to foo
if foo
exists and has a non-null value, then var = foo
; otherwise var = bar
.
Syntax
Similar to a null coalescing operator, this is a compression of the ternary conditional statement:
var = foo ? foo : bar
Or, expanded into an if-then statement:
if (foo != null) var = foo;
else var = bar;
It is useful for writing short conditional statements that depend on the value of a variable without changing the unspecified value (if it exists), and to avoid returning an error if the value of the condition is not set.
PHP
The binary conditional operator has been available in PHP since 5.3. According to the documentation:
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expressionexpr1 ?: expr3
returnsexpr1
ifexpr1
evaluates to TRUE, andexpr3
otherwise.[7]
It can be used to redefine an existing variable which may or may not be set:
$foo = $foo ?: $bar;
It can also be used to echo or return the resulting value instead of assigning it to a variable, as with use of the ternary operator in PHP:
echo $foo ?: $bar;
return $foo ?: $bar;
The Elvis operator may be combined with other operators, or in a nested conditional operator statement, where it is treated as a ternary operator "short cut". However, due to an error in the language grammar of PHP, this is rarely done.[8] The ternary operator is left-associative in PHP, which is the opposite of the expected behavior; so combining several conditional operators may result in a statement which may be difficult to read, or produce extremely non-intuitive results.[9]
For example, in PHP, $var = $foo ? $bar : $bar ?: $baz
unintuitively evaluates to:
$var = ($foo ? $bar : $bar) ?: $baz
# which is equivalent to
$var = $bar ?: $baz
regardless of the value of $foo
. The expected behavior must be specified with parentheses:
$var = $foo ? $bar : ($bar ?: $baz)
Groovy
Groovy uses the '?:' operator, referred to as the "Elvis Operator" in the language documentation.[5]
def title = suppliedTitle ?: "Default Title"
C
GCC and related compiler suites[10] support the ?:
operator when compiling C or Objective-C code:[11]
char* valueOrNull = ...;
char* nonNullValue = valueOrNull ?: "Some Default Value";
The compression of the ternary conditional is useful when the operand is expensive to compute or has a side effect.[11] The ternary version var = foo() ? foo() : bar
contains two calls to the evaluated function, performing twice its effects when it first evaluates to true.
C#
The binary conditional operator is available in C# as of version 6.0.
var g1 = parent?.Child?.GrandChild;
if (g1 != null)
{
// does not throw NullReferenceException, even when parent or parent.Child are NULL
}
Angular2
Elvis operator is also available with Angular2. In Angular it's a fluent and convenient way to guard against null and undefined values in property paths.
The current hero's name is {{currentHero?.firstName}}
Here it is, protecting against a view render failure if the currentHero
is null
.
Related expressions
Similar to PHP's short-hand operator, JavaScript programmers have long used the OR operator, which functionally produces similar results.
var aVar = bVar || cVar;
// equivalent to `var aVar = bVar ? bVar : cVar`
// or in PHP expression `$aVar = $bVar ?: $cVar`
The same can be done with Perl's ||
operator and Python's or
operator.
See also
- ?: or conditional operator, when used as a ternary operator
- Null coalescing operator, ?? or // operator
- Spaceship operator
References
- ↑ "coding style - ?: operator". Stack Overflow. Retrieved 2014-02-17. Lay summary – elvis emoticon graphic.
- ↑ Joyce Farrell. Java Programming. p. 276. ISBN 978-1285081953.
The new operator is called Elvis operator because it uses a question mark and a colo together (?:)
- ↑ "PHP 5.3.0 Release Announcement". PHP website. Retrieved 2014-02-17.
Syntax additions: NOWDOC, ternary short cut "?:"
- ↑ https://github.com/getrailo/railo/wiki/Operators#elvis-operator
- 1 2 "Elvis Operator (?: )".
- ↑ "What is the PHP ? : operator called and what does it do?". Retrieved 2014-02-17.
- ↑ "PHP: Comparison Operators - Manual". PHP website. Retrieved 2014-02-17.
- ↑ "PHP Bug #61915: incorrect associativity of ternary operator". PHP website. 2012-05-02. Retrieved 2014-02-17.
We can't fix this without breaking code
- ↑ "Comparison Operators, Example #3: Non-obvious Ternary Behaviour". PHP website. Retrieved 2014-02-17.
- ↑ http://clang.llvm.org/docs/LanguageExtensions.html
- 1 2 https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals
- ↑ "Angular 2". angular.io. Retrieved 2016-04-24.