I am following the LearnRubyTheHardWay tutorial and having a difficulty in modifying the exercise 29. Everything works fine if I define the variables like (as in the tutorial):
people = 100000
cats = 34
dogs = 56
However, if I try to get the variables from STDIN like:
puts "How many people are here?"
people = STDIN.gets.chomp()
puts "How many cats?"
cats = STDIN.gets.chomp()
puts "And how many dogs?"
dogs = STDIN.gets.chomp()
The equality operators return false results as if they only do calculate the results using the first two digits of the numbers. So if I type 100000000 to people and 11, 12 or 13 to cats, the methods return "Too many cats.." If I type 150000000 to people and anything <15 to cats, they return "Not many cats.." Additionally I have to modify
dogs += 5
to
dogs += "5"
otherwise I get the following error: in `+': can't convert Fixnum into String (TypeError)
If I leave the double quotes in place and revert to people = 10000 stuff, I get the following error: in `+': String can't be coerced into Fixnum (TypeError)
So to say, I have no problem with the code in the tutorial, just try to learn what causes the errors introduced by the STDIN methods. I looked into the RubyDoc.org, to see whether it is an issue with fixnum, integer or string classes or anything related to chomp or gets methods but couldn't find the reason. I also tried to_i and to_s before or after but didn't get any result.
The full source code of the file is below:
puts "How many people are here?"
people = STDIN.gets
puts "How many cats?"
cats = STDIN.gets
puts "And how many dogs?"
dogs = STDIN.gets
#people = 100000
#cats = 34
#dogs = 56
puts "So, %d people, %d cats and %d dogs, huh?" % [people,cats,dogs]
if people < cats
puts "Too many cats! The world is doomed!"
end
if people > cats
puts "Not many cats! The world is saved!"
end
if people < dogs
puts "The world is drooled on!"
end
if people > dogs
puts "The world is dry!"
end
dogs += "5"
puts "Now there are #{dogs} dogs."
if people >= dogs
puts "People are greater than or equal to dogs."
end
if people <= dogs
puts "People are less than or equal to dogs."
end
if people == dogs
puts "People are dogs."
end
The problem is that STDIN.gets returns a string. All the comparison operations will therefore operate on strings. Example:
people = "100000000"
cats = "11"
puts people < cats # => true!
This is because < will compare the strings lexicographically (and 1000... comes before 11 in the alphabet). There is actually one point in your example that makes it pretty obvious what's going on here:
dogs = STDIN.gets
dogs += "5"
If you input 7 here, it should print out 75. You see, it just concatenates the strings.
How to fix this? Easy, just convert the strings to integers:
puts "How many people are here?"
people = STDIN.gets.to_i
puts "How many cats?"
cats = STDIN.gets.to_i
puts "And how many dogs?"
dogs = STDIN.gets.to_i
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With