Reputation: 1612
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
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
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
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
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