Dave Burt
3/30/2006 10:18:00 AM
Hi Jan,
Have you been typing his examples into IRB and running them as you go? I
found that technique really useful learning Perl - try variations on the
example code until you understand it. Try reading Chapter 6 again with IRB,
including the mini exercise in the Looping section.
But let's unpack your code while it's here:
Jan K wrote:
> Here's what I had when I gave up:
>
> ------------------------------------------
> input = gets.chomp
> number = rand(21)
>
> number2 = 0
> keep_count = 0
>
> if keep_count != 3
> while
> input != 'BYE'
> puts 'HUH?! SPEAK UP, SONNY!'
> keep_count = 0
> input = gets.chomp
> while
> input == 'BYE'
> puts 'HUH?! SPEAK UP, SONNY!'
> number2 = (keep_count + 1)
> keep_count = number2
> input = gets.chomp
> end
> end
> else
> puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!'
> end
> -----------------------------------------
>
>
> And here's the regular Deaf Grandma solution that I used:
>
> ----------------------------------------
> input = gets.chomp
> number = rand(21)
>
> if
> while
> input != 'BYE'
> puts 'HUH?! SPEAK UP, SONNY!'
> input = gets.chomp
> end
> else
> puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!'
> end
> -------------------------------------
When you start dealing with flow control, you'll find that indenting makes a
big difference to how easy it is to read and understand your code. Let's
start by indenting your Grandma code:
if
while
input != 'BYE'
puts 'HUH?! SPEAK UP, SONNY!'
input = gets.chomp
end
else
puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!'
end
Note in all Chris' examples, "if" and "while" are always followed by a
condition. If Ruby expects something, but doesn't get it, it'll wait until
the following line. That's what's happening with your if and while. It's the
same as this:
if (while input != 'BYE'
puts 'HUH?! SPEAK UP, SONNY!'
input = gets.chomp
end)
else
....
See, while's condition is "input != 'BYE'", and if's condition is the result
of the whole while loop. The result of a while loop is always nil, so the
condition is always false, so you get 'NO, NOT SINCE'...
That means this section of your program is the same as this:
while input != 'BYE'
puts 'HUH?! SPEAK UP, SONNY!'
input = gets.chomp
end
puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!'
Indenting and putting the condition on the same line as the "if" or "while"
make the flow of your other program a little easier to see, too.
if keep_count != 3
while input != 'BYE'
puts 'HUH?! SPEAK UP, SONNY!'
keep_count = 0
input = gets.chomp
while input == 'BYE'
puts 'HUH?! SPEAK UP, SONNY!'
number2 = (keep_count + 1)
keep_count = number2
input = gets.chomp
end
end
else
puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!'
end
Note you've got a loop inside a loop. To get out of that, the inside loop
has to exit, and then the outside loop, and if you look at their respective
conditions (input == 'BYE') and (input != 'BYE'), that will never happen.
Try going back to the example in the Looping section, and modifying that
little bits at a time. Indent lines inside control structures to help you
see at a glance where they begin and end.
Cheers,
Dave