30

With the ruby ternary operator we can write the following logic for a simple if else construct:

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

But what if I wanted to write this as if foo 'a' elsif bar 'b' else 'c'?

I could write it as the following, but it's a little difficult to follow:

foo = true
a = foo  ? 'a' : (bar ? 'b' : 'c') #=> "a"

foo = false
bar = true
a = foo  ? 'a' : (bar ? 'b' : 'c') #=> "b"

Are there any better options for handling such a scenario or is this our best bet if we wish to condense if..elsif..else logic into a single line?

Noz
  • 6,216
  • 3
  • 47
  • 82
  • 3
    I think the problem with the lack of readability in the nested ternary solution is that putting all of this on one line is inherently difficult to read, and none of the solutions you come up with are going to be much easier to parse. – John Biesnecker Dec 12 '12 at 21:27
  • 5
    In other words, with more experience you will learn that squeezing as much code into as small a space as possible is never a valid goal. – Ed S. Dec 12 '12 at 21:34
  • 3
    "squeezing as much code into as small a space as possible is never a valid goal." except in machine-code. – the Tin Man Dec 12 '12 at 22:24

4 Answers4

54
a = (foo && "a" or bar && "b" or "c")

or

a = ("a" if foo) || ("b" if bar) || "c"
sawa
  • 165,429
  • 45
  • 277
  • 381
20

The Github Ruby Styleguide recommends that one liners be reserved for trivial if/else statements and that nested ternary operators be avoided. You could use the then keyword but its considered bad practice.

if foo then 'a' elsif bar then 'b' else 'c' end

You could use cases (ruby's switch operator) if find your control statements overly complex.

sunnyrjuneja
  • 6,033
  • 2
  • 32
  • 51
5

a = if foo then 'a' elsif bar then 'b' else 'c' end

tjmw
  • 299
  • 2
  • 4
3

You can also write:

x = if foo then 'a' elsif bar then 'b' else 'c' end

However, this isn't idiomatic formatting in Ruby.

tokland
  • 66,169
  • 13
  • 144
  • 170