From: Dave Burt Date: 2006-03-30T19:18:42+09:00 Subject: Re: Learn to Program, by Chris Pine 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