# Deaf grandma - almost there

**URL:** <https://www.ruby-forum.com/t/deaf-grandma-almost-there/188805>\
**Category:** Ruby\
**Created:** [May 18, 2010, 7:04pm UTC](https://www.ruby-forum.com/t/deaf-grandma-almost-there/188805 "2010-05-18T19:04:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mangoloid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b38774/32.png) [@mangoloid](https://www.ruby-forum.com/u/mangoloid)\
**Post date:** [May 18, 2010, 7:04pm UTC](https://www.ruby-forum.com/t/deaf-grandma-almost-there/188805/1 "2010-05-18T19:04:51Z")

</div>

From the Chris P. 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”

---

<div class="post-metadata">

**Author:** ![mangoloid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b38774/32.png) [@mangoloid](https://www.ruby-forum.com/u/mangoloid)\
**Post date:** [May 18, 2010, 7:16pm UTC](https://www.ruby-forum.com/t/deaf-grandma-almost-there/188805/2 "2010-05-18T19:16:37Z")

</div>

On Tue, May 18, 2010 at 11:04 AM, Stephen Hau  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Ruby’s random number generator at the end of the methods Â chapter.)  
> in a row. Make sure to test your program: if you shout BYE three  
> Â puts ‘SPEAK UP!’
> 
> Â Â 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 N.

---

<div class="post-metadata">

**Author:** ![mangoloid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b38774/32.png) [@mangoloid](https://www.ruby-forum.com/u/mangoloid)\
**Post date:** [May 18, 2010, 7:41pm UTC](https://www.ruby-forum.com/t/deaf-grandma-almost-there/188805/3 "2010-05-18T19:41:50Z")

</div>

Jonathan N. wrote:

> 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 N.

Thanks Jonathan, that fixed it! I guess I got ahead of myself by using a  
method before fully understanding scope. Lesson learnt 🙂
