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.

Was it helpful?

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top