Determine if a string is a valid float value

Here's one way:

class String
  def valid_float?
    # The double negation turns this into an actual boolean true - if you're 
    # okay with "truthy" values (like 0.0), you can remove it.
    !!Float(self) rescue false
  end
end

"a".valid_float? #false
"2.4".valid_float? #true

If you want to avoid the monkey-patch of String, you could always make this a class method of some module you control, of course:

module MyUtils
  def self.valid_float?(str)
    !!Float(str) rescue false
  end
end
MyUtils.valid_float?("a") #false

An interesting fact about the Ruby world is the existence of the Rubinius project, which implements Ruby and its standard library mostly in pure Ruby. As a result, they have a pure Ruby implementation of Kernel#Float, which looks like:

def Float(obj)
  raise TypeError, "can't convert nil into Float" if obj.nil?

  if obj.is_a?(String)
    if obj !~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/
      raise ArgumentError, "invalid value for Float(): #{obj.inspect}"
    end
  end

  Type.coerce_to(obj, Float, :to_f)
end

This provides you with a regular expression that matches the internal work Ruby does when it runs Float(), but without the exception. So you could now do:

class String
  def nan?
    self !~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/
  end
end

The nice thing about this solution is that since Rubinius runs, and passes RubySpec, you know this regex handles the edge-cases that Ruby itself handles, and you can call to_f on the String without any fear!


# Edge Cases:
# numeric?"Infinity" => true is_numeric?"Infinity" => false


def numeric?(object)
true if Float(object) rescue false
end

#Possibly faster alternative
def is_numeric?(i)
i.to_i.to_s == i || i.to_f.to_s == i
end