Ruby’s other ternary operator

This may be a well-know Ruby trick, but I thought I’d share it anyway.

Ruby has the ternary operator:

a = true  ? 'a' : 'b' #=> "a"
b = false ? 'a' : 'b' #=> "b"

But it also has something else…

a = (true  && 'a') || b #=> "a"
b = (false && 'a') || b #=> "b"

All statements in Ruby return the value of the last expression evaluated, so true && 'a' returns ‘a’, and the ‘b’ is ignored (via boolean short-circuiting). false && 'a' evaluates to false, so Ruby moves on, and returns ‘b’.

This is a lot like the a ||= 'a' trick, which expands to a = a || 'a', giving the variable a default value, if it’s not already initialized.

If Ruby already has the ternary operator, why bother? Personally, I find this form more natural (which surprised me, after years of using the ternary operator in Java and C#). For some reason, it reads more like natural language to me.

var user_name = (user.authenticated? && user.name) || 'guest'

Does anyone else see it?

7 Responses to “Ruby’s other ternary operator”


  1. 1 Reg Braithwaite 2007-06-12 at 06:52

    This is a well known Ruby trick, but it is not exactly the same thing as the ternary operator. Let’s compare:

    a ? b : c

    and

    (a && b) || c

    The former gives b whenever a is truthy and c otherwise, always. So if a == true, b == nil, and c == ‘cee-threepio’, (a ? b : c) => nil.

    But (a && b) || c => ‘cee-threepio’ for the same values.

    I prefer this form as well, but only when I know that the value of ‘b’ is guaranteed to be truthy.

  2. 2 Simen 2007-06-12 at 07:04

    You don’t need the parantheses around your third and fourth lines. It works anyway:

    irb(main):001:0> a = true ? "a" : "b"
    => "a"
    irb(main):002:0> b = false ? "a" : "b"
    => "b"
    irb(main):003:0> a = true && "a" || b
    => "a"
    irb(main):004:0> b = false && "a" || b
    => "b"

    However, if you change && to “and”, you start running into dark corners of operator precedence:

    irb(main):001:0> a = true ? "a" : "b"
    => "a"
    irb(main):002:0> b = false ? "a" : "b"
    => "b"
    irb(main):003:0> a = true and "a" || b
    => "a"
    irb(main):004:0> b = false and "a" || b
    => false

    And why do you put “var” before user_name? Ruby isn’t javascript.

  3. 3 Daniel Bernier 2007-06-12 at 07:59

    Reg, you’re right, I didn’t think of that. I’ll have to scan through the areas I’ve used this, and see whether that could happen…

    Simen,
    > You don’t need the parantheses around your third and fourth lines.

    Yeah, I included them to emphasize the grouping, for clarity.

    > And why do you put “var” before user_name? Ruby isn’t javascript.

    You’re right…I think that ‘var’ snuck in from the javascript I’ve been doing, and the Scala I’ve been reading about.

  4. 4 raichu 2007-06-14 at 07:35

    i think that’s how python programmers tried to get the convenience of the ternary operator into their programming language before they got their chainable syntax in version 2.5. back then, their version also failed when the variable wasn’t “truthy-worthy”.

  5. 5 she 2008-03-12 at 05:47

    actually i think this is rather ugly

    and ternay operator is ugly too but at least used often enough to know it
    and sometimes it reduces a few lines of code

  6. 6 shawn 2008-09-26 at 23:30

    you cant do this if the action you want done is a binary opertor, ie only test if a test operator was given:
    (action ? params[:action] == action : true)

  7. 7 Otto 2009-06-23 at 21:47

    I think the ternary operator sucks. Ok, it’s fairly easy to understand a, b and c, but when that involves more complex expressions, it’s a pain. And there are those who like to put a ternary operator inside another operator…


Leave a Reply




Say Hello

danbernier [at] gmail [dot] com
Twitter @danbernier
Hartford.rb
LinkedIn

Tweeting:

  • @dchec Invite them behind the counter, and move the event to a small town. You never know. 2 days ago
  • @kdaigle Where's the new digs again? Congrats on the move! 2 days ago
  • "Persuading the world to adopt a new kind of arithmetic is quixotic, like trying to replace the QWERTY keyboard." http://bit.ly/TWv5P DANG! 2 days ago
  • @soderberg Sessions Woods is beautiful in the spring -- when the swamps start flowering, it's pretty amazing. On of my favorite local hikes. 3 days ago
  • "Anything which has to call itself a science isn't." - Fred Brooks, "The Computer Scientist as a Toolsmith" http://bit.ly/vXLoj 4 days ago

I’m a BackPack fan

Backpack

Categories