The reason why your current code fails is because you use false
as rescue value. You can't compare false >= 1
. Sticking close to your original code you might wrap the comparison into a begin
/end
block.
loop do
puts "How many soaps are you looking to purchase? (Please put an integer)"
x = gets.chomp
begin
barsofsoap = Integer(x)
if barsofsoap >= 1
break
end
rescue ArgumentError => _error
puts "You didn't put an integer, please put an integer and try again."
end
end
Or simplifying the code:
loop do
puts "How many soaps are you looking to purchase? (Please put an integer)"
break if (barsofsoap = gets.to_i).positive?
puts "Invalid input. Provide a positive integer."
end
The above code doesn't detect if the input is a string or an integer. By replacing Integer(x)
with x.to_i
it would simply return 0
if invalid. Since you want the user to provide an positive integer it still requests them to provide a new integer.
nil.to_i #=> 0
''.to_i #=> 0
'asdf'.to_i #=> 0
'12.34'.to_i #=> 12
Like shown above the string '12.34'
will produce the value 12
. Depending on your requirements you might not want to use this value and instead mark it as invalid input. In this case you could use a regex to check the provided input.
loop do
puts "How many soaps are you looking to purchase? (Please put an integer)"
input = gets
break barsofsoap = input.to_i if input.match?(/\A[1-9]\d*\Z/)
puts "Invalid input. Provide a positive integer."
end
The regex /\A[1-9]\d*\Z/
will match the following:
\A
Matches start of string.
[1-9]
Matches one of the digits 1-9
.
\d*
Matches zero or more digits 0-9
.
\Z
Matches end of string. If the string ends with a newline, it matches just before the newline.
if barsofsoap >= 1
is in fact the right way to check this.match
would work for a String type, but yourbarsofsoap = Integer(x)
ensures that you're dealing with a numeric type. Try it again! – Chris Heald