72

I keep it in single line, if it's short. Lately I've been using this style for longer or nested ternary operator expressions. A contrived example:

$value = ( $a == $b ) 
            ? 'true value # 1'
            : ( $a == $c )
                ? 'true value # 2'
                : 'false value';

Personally which style you use, or find most readable?

Edit: (on when to use ternary-operator)

I usually avoid using more than 2 levels deep ternary operator. I tend prefer 2 levels deep ternary operator over 2 level if-else, when I'm echoing variables in PHP template scripts.

ysth
  • 96,171
  • 6
  • 121
  • 214
Imran
  • 87,203
  • 23
  • 98
  • 131
  • Tentatively tagged this PHP, but I am not sure this is the language. – ddaa Oct 28 '08 at 20:35
  • It is. I didn't tag it PHP as the topic applies to all languages with C-like syntax – Imran Oct 30 '08 at 00:05
  • Added language-agnostic (since it is) but kept php (since the example is). – ysth Nov 12 '08 at 07:52
  • This isn't really a good format for StackOverflow (see [the FAQ](http://stackoverflow.com/faq#dontask), since it's not something that can have a "right" answer. You might have better luck on the Programmers SE. – me_and Sep 14 '12 at 09:21
  • Try asking at [Code Review](http://codereview.stackexchange.com). – kenorb Jul 25 '14 at 09:33
  • I often used it together with *short open tags* [`=$x?"foo":"bar";?>`](https://eval.in/836357). Idk where to read more about this syntax (: – bobble bubble Jul 22 '17 at 22:54

15 Answers15

104

The ternary operator is generally to be avoided, but this form can be quite readable:

  result = (foo == bar)  ? result1 :
           (foo == baz)  ? result2 :
           (foo == qux)  ? result3 :
           (foo == quux) ? result4 : 
                           fail_result;

This way, the condition and the result are kept together on the same line, and it's fairly easy to skim down and understand what's going on.

Simon Howard
  • 8,999
  • 5
  • 28
  • 21
  • If I'd really *have* to use it, I'd probably use this layout. +1 – Tomalak Oct 28 '08 at 13:43
  • 62
    If I'd have to use it this way, I'd use a switch statement. – pilsetnieks Oct 28 '08 at 13:49
  • 18
    In this particular situation, you could use a switch statement, as they're == comparisons, but they could be any expressions. In the general case, a switch statement isn't always possible. – Simon Howard Oct 28 '08 at 13:52
  • This is why I think more languages need a "select" construct which is to "switch" as the ternary operator is to if/else. Basically, it's a control structure that returns a value. I've only ever seen it in VHDL, and I think Matlab. – rmeador Oct 28 '08 at 14:03
  • I consider syntactic sugar misused a code smell. Nesting ternaries definitively falls into this category. – Tomalak Oct 28 '08 at 14:42
  • @Nouveau: you can't use a switch if bar, baz, qux and quux are not constants -- certainly not in the majority of languages. – Jonathan Leffler Oct 28 '08 at 15:01
  • @meador: Take a look at Ruby. :) – unwind Oct 29 '08 at 14:27
  • Which more or less defines "not in the majority of languages". :-D – Tomalak Nov 06 '08 at 16:31
  • 2
    @rmeador: So you're thinking of something like lisp's COND, then? (setq foo 3) (cond ((>= foo 4) 'result1) ((= foo 3) 'result2) ((= foo 2) 'result3) ((<= foo 1) 'result4)) returns result2. –  Nov 12 '08 at 08:00
  • Hm... SO's comments clobber newlines. Imagine that COND well-formatted. –  Nov 12 '08 at 08:01
  • 7
    This structure needs alot more parenthesis before it will work correctly in PHP! – too much php Sep 25 '09 at 02:28
  • @simon, you can use a switch statement like `switch(true)` then put an expression to be evaluated in each `case`. – JD Isaacks Sep 24 '10 at 19:26
  • @John - erm, no, you can't, at least in curly braces languages. The expressions in the case statement have to reduce to an integer constant. – Simon Howard Sep 30 '10 at 09:10
  • @Simon then I must be using a magic version of PHP. – JD Isaacks Sep 30 '10 at 13:21
  • 22
    "The ternary operator is generally to be avoided" - Why? This seems more like an opinion rather than a rule. The ternary operator is a useful tool in many situations where an if-else would seem like overkill. Maybe we should also avoid PHP, because people don't know how to use that properly too? – Ryall Feb 27 '12 at 12:45
  • 1
    @pilsetnieks, Ternary operators have return values. Switch statements don't. In the code above, `result` would always be defined. The code that would follow could rely on that. In a switch statement `result` wold be less reliable as it would depend on each individual switch case. – Emanuil Rusev Sep 17 '13 at 14:00
  • this is not nesting, nesting is when you have more than one consecutive conditions, rather than falling back immediately – neaumusic Nov 11 '17 at 00:11
83

I try not to use a ternary operator to write nested conditions. It defies readability and provides no extra value over using a conditional.

Only if it can fit on a single line, and it's crystal-clear what it means, I use it:

$value = ($a < 0) ? 'minus' : 'plus';
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • 9
    100% agreed. and ONLY if the operator is used as a single statement and ONLY if it's less than 80 chars, including indentation. at a previous employer, the previous lead dev liked to use the ternary op in the middle of 1k echo statements. EVIL. I outlawed its use altogether in that codebase. – jcoby Oct 29 '08 at 17:22
  • 1
    I compared my if-block to its alternative as a ternary statement, and when the ternary had some formatting (parens, spacing, etc), it was 20 bytes larger than my if-block, and it was practically unreadable. When I optimized the ternary (but not the if-block), it was only two bytes smaller than the if-block and even less readable than before. – ICoffeeConsumer May 25 '13 at 23:00
  • Its easy to pooh-pooh nested ternary operators, but if you're writing an Automapper configuration and you need an expression that's supported by Linq-to-SQL, suddenly they don't seem so bad. – user2880616 Mar 01 '17 at 22:21
27

a style I sometimes use, which I'm bringing up since it hasn't been mentioned, is like this:

$result = ($x == y)
        ? "foo"
        : "bar";

..but usually only if putting it all on one line makes it too long. I find that having the = ? : all line up makes it look neater.

nickf
  • 537,072
  • 198
  • 649
  • 721
  • I style it the same except I don't line them up (I only indent with tabs, I don't mix tabs and spaces together, bad style IMO). – jurchiks May 30 '13 at 16:24
25

Personally, I only use the ternary operator if it fits on one line. If it need to span, then it's time for the good old

if else if else
biozinc
  • 4,629
  • 2
  • 25
  • 28
17

PHP nested ternary operators behave differently.

This syntax passes all the following tests. Based on http://deadlytechnology.com/web-development-tips/php-ternary-syntax/

$myvar = ($x == $y)
?(($x == $z)?'both':'foo')
:(($x == $z)?'bar':'none');

.

See: http://au.php.net/ternary

Example #3 "Non-obvious Ternary Behaviour" explains why the following does not work in PHP.

$x = 1;
$y = 2;
$z = 3;   
$myvar = ($x == $y) 
       ? "foo" 
       : ($x == $z) 
         ? "bar" 
         : "none";  
$myvar == 'none'; // Good

$x = 1;
$y = 2;
$z = 1;   
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";  
$myvar == 'bar'; // Good

$x = 1;
$y = 1;
$z = 3;   
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";  
$myvar == 'bar'; // Bad!

$x = 1;
$y = 1;
$z = 1;   
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";  
$myvar == 'bar'; // Bad!
Chris Jacob
  • 11,878
  • 7
  • 47
  • 42
  • 2
    Take heed! Nested ternaries in PHP are a tricky beast. Probably advised to steer clear of them, but we all like to dice with the tricky. – Zak Henry Sep 15 '11 at 02:21
13

ternary operators are short effective ways to write simple if statements. They shouldn't be nested or difficult to read. Remember: You write the software once but is is read 100 times. It should be easier to read than write.

Rick Kierner
  • 714
  • 7
  • 20
6

I tend to enclose the condition in parentheses : (a == b) ? 1 : 0

Guillaume Gervais
  • 1,035
  • 2
  • 14
  • 26
  • Why? There is precedence (priority) of operators. For [C++](http://en.cppreference.com/w/cpp/language/operator_precedence), [PHP](http://www.php.net/manual/en/language.operators.precedence.php), ... – Apostle Apr 01 '13 at 14:45
  • Makes it easier to discern the condition from the true/false statements. I put parentheses around any and all conditions in my code. – jurchiks May 30 '13 at 16:23
3

I'll dissent with the common opinion. I'm sort of like Imran with my conditional operator style. If it fits cleanly on one line, I keep it on one line. If it doesn't fit cleanly on one line, I do break it, but I use only a single tab (4 spaces; I have VS set to insert spaces for tabs) for the indent. I don't immediately jump to if-else, because a lot of the time the conditional operator makes more sense contextually. (If it doesn't make sense contextually, however, I simply don't use it.)

Also, I don't nest conditional operators. At that point, I do find it too difficult to read, and it's time to go to the more verbose if-else style.

John Rudy
  • 37,282
  • 14
  • 64
  • 100
3

The ternary conditional can make code cleaner and more elegant, and most importantly, help you put emphasis on the right things and avoid repeating yourself. Consider using them, but do not make the code less readable by doing so. In VB.NET:

    'before refactoring 
    If x = 0 Then                    ' If-Then-Else puts emphasis on flow control
        label = "None"
    Else
        label = Foo.getLabel(x)      '  If-Then-Else forces repeat of assignment line
    End If

    'after refactoring    
    label = If(x = 0, "None", Foo.getLabel(x)) ' ternary If puts emphasis on assignment

Note that "it is less readable" is not the same thing as "I'm not used to seeing that".

Patrick Szalapski
  • 8,738
  • 11
  • 67
  • 129
2

The "contrived example" is how I would indent it, except that I would indent from the left margin, not based on where the ( or whatever is on the line above.

To the ternary detractors - readability is the point. If you don't think it makes for more readable code, don't use it. But I find the contrary to be the case at least some of the time.

ysth
  • 96,171
  • 6
  • 121
  • 214
1

I don't use it. It always smelled to me like trying to save space and typing in source code with the expectation that small source == more efficient compiled code.

I don't find it readable at all, but much of that is because I just never use it.

Tim
  • 20,184
  • 24
  • 117
  • 214
  • 1
    Heh. This is dead on, and that whole attitude pervades the design of C. Arrays == pointers, the comma operator, and the pre and post increment and decrement operators are other sterling examples. This is one of the reasons why I think Ada is better. It was designed for producing maintainable code – T.E.D. Oct 28 '08 at 14:15
1

Imran, you have formatted this beautifully. However, the ternary operator does tend to get unreadable as you nest more than two. an if-else block may give you an extra level of comprehensible nesting. Beyond that, use a function or table-driven programming.

Yuval F
  • 20,565
  • 5
  • 44
  • 69
1
$foo = (isset($bar)) ? $bar : 'default';
1

I personally only use it for an assignment of a variable (in java) for example :

String var = (obj == null) ? "not set" : obj.toString();

and (other example) when using function that doesn't allow null parameter such as :

String val; [...]
int var = (val == null) ? 0 : Integer.parseInt(val);
Vinze
  • 2,549
  • 3
  • 22
  • 23
0

I tend not to use the ternary operator at all as I find if .. else much more readable.

SmacL
  • 22,555
  • 12
  • 95
  • 149