From: Morton Goldberg Date: 2007-05-08T19:22:39+09:00 Subject: Re: Difference answers from Terminal, TextMate, and BBEdit On May 8, 2007, at 12:30 AM, Greg wrote: > On 2007-05-07 20:37:31 -0700, Morton Goldberg > said: > >> 2. Your case statement in the your while loop just doesn't do >> what you think it should. And actually it would be hard make a >> case work in the situation you have set up. >> Here is a modification of your code that I think will do what you >> were trying to achieve: >> >> #!/usr/bin/env ruby >> class OrangeTree >> MSG_GROW = "Type \"year\" to grow your tree." >> MSG_PICK = "Type a number to pick some more fruit. " >> EXIT_TXT = "Something went wrong." >> def initialize >> @heightInches = 0 >> @age = 0 >> @fruit = 0 >> puts MSG_GROW >> end >> def ageOneYear >> @heightInches = @heightInches +1 >> puts 'Height: ' + @heightInches.to_s # <= not '@height' >> @age += 1 >> # @age = @age + 1 >> puts "Got to ageOneYear. Age: #{@age}" >> case @age >> when (1..3) : puts("Your #{@age} year old tree is too >> young to bear fruit yet. #{MSG_GROW}" ) >> when (4..29) : puts(" Age: #{@age}. Place holder until get >> 1..3 working." ) >> when (30) : puts("Your tree was very fruitful, but it >> reached old age and died.") >> else puts( " Something went wrong. #{EXIT_TXT}" ) >> end >> end >> def height >> # returns the height >> end >> def pick_an_orange >> puts 'Got to pick_an_orange, but haven\'t defined yet' >> # reduce this year count by one >> end >> end >> countLoop = 0 >> tree = OrangeTree.new >> while countLoop < 100 >> countLoop += 1 >> puts "countLoop = #{countLoop}" >> # case statement not really appropriate for this loop. >> # Note: gets always returns a string terminated with a newline. >> user_input = gets.chomp >> if user_input == 'year' >> tree.ageOneYear >> elsif (1..100).include?(user_input.to_i) # need to convert >> string to integer >> tree.pick_an_orange >> else puts('Don\'t be greedy, don\'t try to pick more than 100 >> oranges') >> end >> end >> >> Regards, Morton > > No it's not working like I want. But I don't understand why case > isn't appropriate. But your method works right and mine doesn't, so > I don't think I'll worry about it now. You _could_ use a case here, but it would have to be considerably more complicated than the simple case form you wrote. I thought (and still think) an if-elsif-else statement is better for sorting out the user input in this case. A case statement like case when 'year' : tree.ageOneYear # , y as shortcut? when (1..100) : tree.pick_an_orange else puts('Don\'t be greedy, don\'t try to pick more than 100 oranges') end just looks for the first true when-clause. In this case that will always be 'year' because everything but false and nil is true in Ruby. > One question. How is >> elsif (1..100).include?(user_input.to_i) > working? I understand it up through "elsif(1..100)" Is the > user_input changed to integer before the elsif is evaluated. What > does the include? do? (The don't be greedy part was just > placeholder until I worked out the whole orange picking and growing > logic.) user_input is converted to a integer during the evaluation of the elsif. This code is roughly equivalent to: num = user_input.to_i in_range = (1..100).include?(num) elsif in_range ... > BTW, the while loop seemed like a crude work around to keep asking > for inputs. I would like it to stop at 30 in the class (at least > that seems more elegant as that is where the age decisions are made). Do you want to stop after 30 loops (that's easy) or when @age reaches 30 (that's just a little harder)? For the first: tree = OrangeTree.new 30.times do user_input = gets.chomp if user_input == 'year' tree.ageOneYear elsif (1..100).include?(user_input.to_i) # need to convert string to integer tree.pick_an_orange else puts('Don\'t be greedy, don\'t try to pick more than 100 oranges') end end For the second: class OrangeTree attr_reader :age # <= add this to OrangeTree so @age can be queried outside of class def end tree = OrangeTree.new loop do user_input = gets.chomp if user_input == 'year' tree.ageOneYear break if tree.age >= 30 elsif (1..100).include?(user_input.to_i) # need to convert string to integer tree.pick_an_orange else puts('Don\'t be greedy, don\'t try to pick more than 100 oranges') end end Regards, Morton