[ruby] Checking if a variable is an integer

Does Rails 3 or Ruby have a built-in way to check if a variable is an integer?

For example,

1.is_an_int #=> true
"[email protected]".is_an_int #=> false?

This question is related to ruby ruby-on-rails-3

The answer is


Use a regular expression on a string:

def is_numeric?(obj) 
   obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end

If you want to check if a variable is of certain type, you can simply use kind_of?:

1.kind_of? Integer #true
(1.5).kind_of? Float #true
is_numeric? "545"  #true
is_numeric? "2aa"  #false

To capitalize on the answer of Alex D, using refinements:

module CoreExtensions
  module Integerable
    refine String do
      def integer?
        Integer(self)
      rescue ArgumentError
        false
      else
        true
      end
    end
  end
end

Later, in you class:

require 'core_ext/string/integerable'

class MyClass
  using CoreExtensions::Integerable

  def method
    'my_string'.integer?
  end
end

I have had a similar issue before trying to determine if something is a string or any sort of number whatsoever. I have tried using a regular expression, but that is not reliable for my use case. Instead, you can check the variable's class to see if it is a descendant of the Numeric class.

if column.class < Numeric
  number_to_currency(column)
else
  column.html_safe
end

In this situation, you could also substitute for any of the Numeric descendants: BigDecimal, Date::Infinity, Integer, Fixnum, Float, Bignum, Rational, Complex


There's var.is_a? Class (in your case: var.is_a? Integer); that might fit the bill. Or there's Integer(var), where it'll throw an exception if it can't parse it.


You can use triple equal.

if Integer === 21 
    puts "21 is Integer"
end

In case you don't need to convert zero values, I find the methods to_i and to_f to be extremely useful since they will convert the string to either a zero value (if not convertible or zero) or the actual Integer or Float value.

"0014.56".to_i # => 14
"0014.56".to_f # => 14.56
"0.0".to_f # => 0.0
"not_an_int".to_f # 0
"not_a_float".to_f # 0.0

"0014.56".to_f ? "I'm a float" : "I'm not a float or the 0.0 float" 
# => I'm a float
"not a float" ? "I'm a float" : "I'm not a float or the 0.0 float" 
# => "I'm not a float or the 0.0 float"

EDIT2 : be careful, the 0 integer value is not falsey it's truthy (!!0 #=> true) (thanks @prettycoder)

EDIT

Ah just found out about the dark cases... seems to only happen if the number is in first position though

"12blah".to_i => 12

If you're uncertain of the type of the variable (it could be a string of number characters), say it was a credit card number passed into the params, so it would originally be a string but you want to make sure it doesn't have any letter characters in it, I would use this method:

    def is_number?(obj)
        obj.to_s == obj.to_i.to_s
    end

    is_number? "123fh" # false
    is_number? "12345" # true

@Benny points out an oversight of this method, keep this in mind:

is_number? "01" # false. oops!

A more "duck typing" way is to use respond_to? this way "integer-like" or "string-like" classes can also be used

if(s.respond_to?(:match) && s.match(".com")){
  puts "It's a .com"
else
  puts "It's not"
end

If you want to know whether an object is an Integer or something which can meaningfully be converted to an Integer (NOT including things like "hello", which to_i will convert to 0):

result = Integer(obj) rescue false

Basically, an integer n is a power of three, if there exists an integer x such that n == 3x.

So to verify that you can use this functions

def is_power_of_three(n)
  return false unless n.positive?

  n == 3**(Math.log10(n)/Math.log10(3)).to_f.round(2)
end

Probably you are looking for something like this:

Accept "2.0 or 2.0 as an INT but reject 2.1 and "2.1"

num = 2.0

if num.is_a? String num = Float(num) rescue false end

new_num = Integer(num) rescue false

puts num

puts new_num

puts num == new_num