0

Writing an age checker program, am adding code to check for input error.

I'm having a problem understanding what the issue is with a section of code, ruby returns a (NoMethodError) for .to_i methods passed into some string objects.

The full code is as follows;

def calculate_difference(year,month,day)
  years = Time.new.year - year
  months = Time.new.month - month
  days = Time.new.day - day 
  if months == 0
    if days < 0
        age = years - 1
    elsif days >= 0
        age = years
    end
  elsif months > 0
    age = years
  else
    age = years - 1
  end
end

puts "What year were you born in?"
year = gets.chomp
while year.to_i < 1900 or year.to_i > Time.new.year - 5
  puts "Please enter a year between 1900 and 5 years ago"
  year = gets.chomp
end
puts "And the month?"
month = gets.chomp
while month.to_i > 12 or month.to_i <= 0
  puts "MONTH please, numbers from 1 to 12..."
  month = gets.chomp
end
puts "And the day number?"
day = gets.chomp

#The offending block of code:

if month.to_i = 1 or month.to_i = 3 or month.to_i = 5 or month.to_i = 7 or month.to_i = 8 or month.to_i = 10 or month.to_i = 12
  while day.to_i > 31 or day.to_i <= 0
  puts "Your month of birth has 31 days, please select a date within the correct range"
  day = gets.chomp
  end
end
if month.to_i = 2
  while day.to_i > 28 or day.to_i < 0
    puts "Incorrect day selected for February"
    day = gets.chomp
  end
end

 stringdate = year+month+day
    stringdate = stringdate.gsub(" ","")
    while stringdate.length != 8
        puts "in number format please: yyyy/mm/dd"
        puts "What year were you born in?"
        year = gets.chomp
        puts "And the month?"
        month = gets.chomp
        puts = "And the day number?"
        day = gets.chomp
    end
    year = year.to_i
    month = month.to_i
    day = day.to_i

    puts "Congratulations, you are #{calculate_difference(year,month,day)} years old."

I'm not sure why it is throwing back an error, as I'm sure strings integers respond to the .to_i method.

error

Barris
  • 969
  • 13
  • 29
  • 5
    You're using `=` when you should be using `==` – Ajedi32 Aug 11 '15 at 21:12
  • To expand on what @Ajedi32 wrote: the _double_ equals sign `==` is the equality operator, used to determine whether two values are equal; that's the one you want. The single equals `=` is the assignment operator, used for assigning the value on the right to the variable on the left. (For more about this last part, see http://stackoverflow.com/questions/5046831/why-use-rubys-attr-accessor-attr-reader-and-attr-writer) – Reinstate Monica -- notmaynard Aug 11 '15 at 21:16
  • To expand on what @iamnotmaynard wrote: all conditions should be written as `const-value equal variable` this means that all `lvalue` items as variables can't `accidentally` assign new value. `item == 0` bad choice, but `0 == item` much better – gaussblurinc Aug 11 '15 at 21:19
  • Noted, thanks for the help – Barris Aug 12 '15 at 09:51

2 Answers2

2

The error message reads "undefined method 'to_i='" and not 'to_i'

This is because Ruby interprets the single "=" as if you want to call a setter method on a hypothetical field to_i:

a = "12"
a.to_i == 12
# returns true

a.to_i = 12
# throws undefined method to_i= 

12 = a.to_i
# creates a syntax error with the better message "unexpected ="
# prevents such assigns-equals errors
12 == a.to_i
# returns true
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Meier
  • 3,858
  • 1
  • 17
  • 46
0

"=" is assignment. "==" is checking if they are equal and returns true or false.

if month.to_i == 1 or month.to_i == 3 or month.to_i == 5 or month.to_i == 7 or month.to_i == 8 or month.to_i == 10 or month.to_i == 12
  while day.to_i > 31 or day.to_i <= 0
  puts "Your month of birth has 31 days, please select a date within the correct range"
  day = gets.chomp
  end
end
if month.to_i == 2
  while day.to_i > 28 or day.to_i < 0
    puts "Incorrect day selected for February"
    day = gets.chomp
  end
end

Or more readable:

if [1, 3, 5, 7, 8, 10, 12].include? month.to_i
  while day.to_i > 31 or day.to_i <= 0
    puts "Your month of birth has 31 days, please select a date within the correct range"
    day = gets.chomp
  end
end
if 2 == month.to_i
  while day.to_i > 28 or day.to_i < 0
    puts "Incorrect day selected for February"
    day = gets.chomp
  end
end
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
patapouf_ai
  • 17,605
  • 13
  • 92
  • 132