0
"0".to_i == 0

also:

"abcdefg".to_i == 0

I want to make sure the string I'm parsing really is just a number (0 included).

Ashbury
  • 2,160
  • 3
  • 27
  • 52
  • 3
    possibly duplicate http://stackoverflow.com/questions/1235863/test-if-a-string-is-basically-an-integer-in-quotes-using-ruby – Ilya Feb 18 '16 at 09:48
  • 2
    Are you sure "how to tell `x.to_i` is `0`" is what you want to ask? As you did, `"abcdefg".to_i == 0` tells you exactly that. – sawa Feb 18 '16 at 09:52
  • Pretty easy to understand that "9".to_i == 9, and "0".to_i == 0, and that "xyz".to_i == 0 is what was throwing me off. – Ashbury Feb 18 '16 at 10:09

5 Answers5

3
Integer("0").zero? rescue false
# => true
Integer("1").zero? rescue false
# => false
Integer("abcdefg").zero? rescue false
# => false
sawa
  • 165,429
  • 45
  • 277
  • 381
1
def string_is_integer?(string)
  !string.match(/^(\d)+$/).nil? # \d looks for digits
end

def string_is_float?(string)
  !string.match(/^(\d)+\.(\d)+$/).nil?
end

def string_is_number?(string)
  string_is_integer?(string) || string_is_float?(string)
end

Or, if you don't mind:

def string_is_number?(string)
  begin
    true if Float(string)
  rescue ArgumentError       
  end || false
end
SHS
  • 7,651
  • 3
  • 18
  • 28
  • I went with a variation on your last answer: def is_number? string true if Float(string) rescue false end – Ashbury Feb 18 '16 at 10:07
  • @Ashbury, you should always rescue exceptions explicitly. here, we only want to rescue the `ArgumentError`. but if you use `rescue` by itself, it will rescue `StandardError`. plus, in your version, the code might return `nil` if a new version of Ruby decided to return `nil` from `Float(string)`. my versions ensure that a boolean is returned in all cases and an exception is thrown when something unexpected happens. – SHS Feb 18 '16 at 10:09
  • Thanks for the clarification. I'll use yours. – Ashbury Feb 18 '16 at 10:10
1
def is_zero?(string)   
  (Integer(string) rescue 1).zero?
end     

is_zero? "0"           #=> true
is_zero? "00000"       #=> true
is_zero? "0cat"        #=> false
is_zero? "1"           #=> false
is_zero? "-0"          #=> true
is_zero? "0_000"       #=> true
is_zero? "0x00"        #=> true
is_zero? "0b00000000"  #=> true

Several of these examples illustrate why it's preferable to use Kernel#Integer rather than a regular expression.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
0

First test if the string is integer or not and then match

def is_i?(x)
   !!(x =~ /\A[-+]?[0-9]+\z/)
end

def is_zero?(x)
  return is_i?(x) && x.to_i == 0
end

# is_zero?("0") will return true
# is_zero?("abcde") will return false 

Or you can put these methods in String class like this

class String
    def is_i?
       !!(self =~ /\A[-+]?[0-9]+\z/)
    end

    def is_zero?
        self.is_i? && self.to_i == 0
    end
end

"0".is_zero? # true
"abcde".is_zero? # false
Harry Bomrah
  • 1,658
  • 1
  • 11
  • 14
0

I want to make sure the string I'm parsing really is just a number.

There are two steps involved:

  1. Parsing, i.e. converting the string into a number
  2. Validation, i.e. checking if the string actually is a number

The built-in conversion functions like Integer and Float already perform both steps: they return a numeric result if the string is valid and raise an error otherwise.

Using these functions just for validation and discarding the return value is wasteful. Instead, use the return value and handle the exception, e.g.:

begin
  puts 'Enter a number:'
  number = Float(gets)
rescue
  puts 'Not a valid number'
  retry
end
# do something with number

or something like:

def parse_number(string)
  Float(string) rescue nil
end

number = parse_number(some_string)
if number
  # do something with number
else
  # not a number
end
Stefan
  • 109,145
  • 14
  • 143
  • 218