Cooper Maruyama
Cooper Maruyama

Reputation: 1612

Shortest way to write ternary in Ruby that returns other value for nil?

Often I want to write something that returns "Yes" if true, "No" if false, or "NA" (or any other string really) if nil. Currently I do this:

@contact.boolean ? 'Yes' : (@contact.boolean.nil? ? "NA" : "No")

Is this the shortest way to write this?

Upvotes: 2

Views: 617

Answers (4)

the Tin Man
the Tin Man

Reputation: 160551

Once you get past a single true/false test with a ternary, it begins to become more difficult to understand when reading. That translates into a maintenance issue. I'd recommend moving to a case statement:

case @contact
when true
  'Yes'
when false
  'No'
when nil
  '(NA)'
end

Other languages make chained ternary statements more readable; In Perl complex chains are used because it's easy to build them in a way that makes it easy to see what's going on. Instead of writing this:

$contact == true ? 'Yes' : contact == false ? 'No' : '(NA)';

You can write it:

$contact == true       ? 'Yes'
    : contact == false ? 'No'
    :                    '(NA)';

It's really a good visual hint about the logic to anyone reading the code.

Upvotes: 0

dnatoli
dnatoli

Reputation: 7012

Pretty much. You are trying to return 3 different values with an operator that returns 2 different values, hence you need the double ternery.

Do you need to store true or false in your object? Could you not store "Yes" or "No"? If so, and assuming your property is called something better than boolean, then you could simply write

@contact.correct? || "(NA)"

Upvotes: 0

Ismael
Ismael

Reputation: 16720

What about moving it to a method? Why does it need to be short? If you move it to a method you will only have to call it then.

Upvotes: 0

Jason Swett
Jason Swett

Reputation: 45074

Here's one idea:

> {true => "Yes", false => "No", nil => "N/A"}[true]
 => "Yes" 

So, of course, you would do {true => "Yes", false => "No", nil => "N/A"}[value]

Upvotes: 9

Related Questions