Reputation: 21
I want to check if my variable is either an integer or float. This is for a calculator. I don't want it to be looping indefinitely.
How would I do so? I tried to do the following:
puts "Enter a number: "
num1 = gets.chomp()
while !(num1 == Integer.superclass or num1 == Float.superclass)
puts "Enter an actual number: "
num1 = gets.chomp()
end
Upvotes: 1
Views: 11937
Reputation:
This question wasn't explicitly asked, but if the code is "for a calculator" as stated, I would ask myself what types of numbers are valid. Here are just a few scenarios to consider:
num1 = ".1"
num1 = "1."
num1 = "_0"
num1 = "0_"
num1 = "1_0"
num1 = "1_000"
num1 = "1e+5"
num1 = "1+1"
num1 = "1 % 2"
num1 = "3**2"
num1 = "(0)"
num1 = "2(2-1)"
Some of the above are valid floats or integers as far as Ruby is concerned but possibly shouldn't be for your purposes, and some are NOT valid in Ruby but arguably should be considered valid depending on the ultimate purpose and behavior of your code. Assuming you're just wanting to roughly match Ruby's definitions though, I think the most dependable method is the to use the Float(string)
approach like so:
Float(num1) rescue <do_something>
This approach will only convert a string if the string is a valid float or integer (with the exception of allowing for a leading decimal); otherwise, it will throw an error which would then need to be rescued one way or another. Under tho hood, I believe Ruby just runs a pre-configured regex string match. This approach can be a bit slower to execute because of the time it takes to run the string match and because of the error handling. In addition it does allow for a leading decimal, exponent annotation, and non leading/trailing underscores which may or may not be desirable..
The alternatives on the other hand almost all require first converting your string to a float or integer which has all sorts of problems. Using my potentially problematic examples above for instance:
In addition:
"7 hundred" #=> 7.0 or 7
"5.2" == "5.20" #=> false
The various pitfalls required for conversion from string to numeric make any non-regex, non-Float(string)
, or non-Integer(string)
solution pretty difficult to implement in a dependable way.
Upvotes: 0
Reputation: 458
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
Upvotes: 5
Reputation: 11193
In general, one option:
10.class == Integer # => true
10.5.class == Float # => true
Or, another:
10.is_a? Integer # => true
10.5.is_a? Float # => true
But since the input is a string, this can be a possible solution to check if a string is an integer or a float number, monkey patching the String
class:
module StringFloatOrInteger
def integer_or_float?
begin !!Float(self) rescue false end
end
def integer_not_float?
begin !!Integer(self) rescue false end
end
def integer?
integer_not_float? & integer_or_float?
end
def float?
!integer_not_float? & integer_or_float?
end
end
String.include StringFloatOrInteger
"home".integer? # => false
"home".float? # => false
"10".integer? # => true
"10".float? # => false
"10.5".integer? # => false
"10.5".float? # => true
In your case, you can use like this, asking n times for the input
def get_integer
2.times do # or whatever times
puts "Please enter an integer: "
input = gets.chomp
return input.to_i if input.integer?
end
return nil # or whatever
end
number = get_integer
Upvotes: 2
Reputation: 2830
Since the input is a string, you will need to first convert them to an integer or float
So if you do the following and the input is "hello", it would return 0.0
num1 = gets.chomp.to_f
If you would like to validate strictly if it is an integer, then you can do so by
input = gets.chomp
until input.is_a?(Fixnum) do
print "Please enter a number: "
input = Integer(gets.chomp) rescue nil
end
Upvotes: 1