AnApprentice
AnApprentice

Reputation: 110940

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?

Upvotes: 162

Views: 234916

Answers (12)

Oleksii Danylevskyi
Oleksii Danylevskyi

Reputation: 35

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

Upvotes: 0

mportiz08
mportiz08

Reputation: 10308

You can use the is_a? method

>> 1.is_a? Integer
=> true
>> "[email protected]".is_a? Integer
=> false
>> nil.is_a? Integer
=> false

Upvotes: 315

Cyril Duchon-Doris
Cyril Duchon-Doris

Reputation: 13929

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

Upvotes: 2

Tsoodol
Tsoodol

Reputation: 59

You can use triple equal.

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

Upvotes: 5

Owais Akbani
Owais Akbani

Reputation: 65

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

Upvotes: -1

Vadym Tyemirov
Vadym Tyemirov

Reputation: 8833

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

Upvotes: 1

vish
vish

Reputation: 2436

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

Upvotes: 3

bigpotato
bigpotato

Reputation: 27497

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!

Upvotes: 24

Alex D
Alex D

Reputation: 30445

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

Upvotes: 54

penguincoder
penguincoder

Reputation: 587

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

Upvotes: 0

Jacob Relkin
Jacob Relkin

Reputation: 163228

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

Upvotes: 32

Groxx
Groxx

Reputation: 2499

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.

Upvotes: 5

Related Questions