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?


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.
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.
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.
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”.
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
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)
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…