Elvis operator

This article is about the use of the ?: operator as a binary operator. For use as a ternary operator, see ?:.

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

Main article: ?:

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. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 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.

[12]

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

References

  1. "coding style - ?: operator". Stack Overflow. Retrieved 2014-02-17. Lay summary elvis emoticon graphic.
  2. 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 (?:)
  3. "PHP 5.3.0 Release Announcement". PHP website. Retrieved 2014-02-17. Syntax additions: NOWDOC, ternary short cut "?:"
  4. https://github.com/getrailo/railo/wiki/Operators#elvis-operator
  5. 1 2 "Elvis Operator (?: )".
  6. "What is the PHP ? : operator called and what does it do?". Retrieved 2014-02-17.
  7. "PHP: Comparison Operators - Manual". PHP website. Retrieved 2014-02-17.
  8. "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
  9. "Comparison Operators, Example #3: Non-obvious Ternary Behaviour". PHP website. Retrieved 2014-02-17.
  10. http://clang.llvm.org/docs/LanguageExtensions.html
  11. 1 2 https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals
  12. "Angular 2". angular.io. Retrieved 2016-04-24.
This article is issued from Wikipedia - version of the Sunday, April 24, 2016. The text is available under the Creative Commons Attribution/Share Alike but additional terms may apply for the media files.