Is there a shorter ternary for Ruby?
-
12-11-2019 - |
Question
This is the closest I've found but it deals with booleans instead of numbers: DRY up Ruby ternary
I'm trying to avoid a divide by 0 scenario in Ruby, while keeping the code shorter and easier to read.
I want to make the following bit of code more concise:
number_to_percentage ((percent_complete.nan? ? 0 : (percent_complete * 100)), :precision => 0)
or
number_to_percentage ((percent_complete.nan? ? 0 : percent_complete) * 100, :precision => 0)
It just seems really hard to read right now. There's more chaining involved so the percent_complete
is actually quite a bit longer. I'm also returning this value from a method, so it gets longer yet again.
I'd like to avoid using temporary variables or shortening the method names, so was hoping to learn of another way.
If I can avoid having to type "percent_complete" twice then that pretty much solves it.
Solution
I'd just add a custom helper that deals with NaN in the desired way.
# in app/helpers/extra_number_helper.rb
module ExtraNumberHelpers
def number_or_nan_to_percentage(number, options = { })
number = 0 if(number.respond_to(:nan?) && number.nan?)
number_to_percentage(number, options)
end
end
Then use number_or_nan_to_percentage
when you need special NaN handling. This also has the happy side effect of telling the people working on your code that you are explicitly dealing with NaN as a possible value.
OTHER TIPS
Why don't you define a new method on Numeric?
class Numeric
def safe_to_f
self.nan? ? 0.0 : self.to_f
end
end
If you like you could also add:
class NilClass
def safe_to_f
0.0
end
end
Here's another idea:
class Object
# substitute a different object if 'predicate' is true
# if 'predicate' is :nil?, this is just like ||
def guard(predicate,substitute)
send(predicate) ? substitute : self
end
end
Which would allow you to write:
percent_complete.guard(:nan?, 0)