As @ArupRakshit mentioned in his comment above, gets
always gets you a String
.
What you want to do is get the user's input and determine what it is.
For instance, "1"
is a String
but 1
is a Fixnum
.
[2] pry(main)> "1".class
=> String
[3] pry(main)> 1.class
=> Fixnum
In your comment above, you mentioned that gets.to_i
gives you an integer. There's a problem with that. String#to_i
returns 0 for strings that are not numeric:
[6] pry(main)> gets.to_i
hello
=> 0
[7] pry(main)> "hello".to_i
=> 0
So basically you're getting a String
and will be determining its possible class(es).
# add more Kernel methods here
POSSIBLE_CLASSES = [Integer, Float, Bignum, String]
str = gets.chomp # chomp gets rid of the \n that gets appended
# to your String because you press enter
# As @Stefan does it, but with meta-programming
POSSIBLE_CLASSES.collect { |p|
(Kernel.method(p.name).call(str); p) rescue nil
}.compact
Explanation of the last line:
Kernel.Integer("1")
returns 1
Kernel.Float("1.0")
returns 1.0
So basically, I want to call a Kernel's method which name is the same as my class.
Kernel.method( method_name )
returns the method to me, which I then call with the string str.
Kernel.Integer("hello")
would throw an ArgumentError
; which will be rescued and a nil will be collected.
So basically, the line above will loop through the possible classes and attempt initializing them with the string we got from the console. We collect the class if there's no exception and nil otherwise. Then we compact the array (remove the nils), which will then contain the 'valid' classes.
Note that our code above only supports Kernel
types and can be easily tweaked to support other classes.