From: Jonathan Nielsen Date: 2010-05-19T02:16:09+09:00 Subject: Re: Deaf grandma - almost there On Tue, May 18, 2010 at 11:04 AM, Stephen Hau wrote: > From the Chris Pine tutorial for beginners: > > ** > Write a Deaf Grandma program. Whatever you say to grandma (whatever > you type in), she should respond with HUH?!  SPEAK UP, SONNY!, unless > you shout it (type in all capitals). If you shout, she can hear you > (or at least she thinks so) and yells back, NO, NOT SINCE 1938! To > make your program really believable, have grandma shout a different > year each time; maybe any year at random between 1930 and 1950. (This > part is optional, and would be much easier if you read the section on > Ruby's random number generator at the end of the methods  chapter.) > You can't stop talking to grandma until you shout BYE. > Hint: Don't forget about chomp! 'BYE'with an Enter is not the same as > 'BYE' without one! > Hint 2: Try to think about what parts of your program should happen > over and over again. All of those should be in your while loop. > > ** > Extend your Deaf Grandma program: What if grandma doesn't want you > to leave? When you shout BYE, she could pretend not to hear you. > Change your previous program so that you have to shout BYE three times > in a row. Make sure to test your program: if you shout BYE three > times, but not in a row, you should still be talking to grandma. > > My code is below, and my question is: > Why can't I reset the 'byes' count to zero using the 'reset' method I've > defined? > I know it works when I change the 'else reset' to 'else byes = 0' > > byes = 0 > > def didnthear >  puts 'SPEAK UP!' > end > > def heard >    year = (rand(21) + 1930).to_s >    puts "I heard ya! Not since " + year > end > > def reset >  byes = 0 > end > > while ( byes < 3 ) >  said = gets.chomp > >  if said == 'BYE' >    byes += 1 >  else >    reset >  end > >  if byes >= 3 >    break >  end > >  if said != said.upcase >    didnthear >  else >    heard >  end > end > > puts "heard you 3 times, byeeee" It doesn't work because of scope. When you set 'byes = 0' in def reset, you are setting a local variable with scope inside the reset method. This is not the same as a local variable in the 'main' scope. One way to fix this by using an 'instance' scope. Even though you aren't technically in a class instance, at some level of abstraction the default binding is an instance of a class. So, instead of 'byes' as a variable, you could use '@byes'. -Jonathan Nielsen