co1 = 0
end
Do you see what i mean? is this possibel to do. Or is there another way
that I can achieve the same effect?
Any help? Thanks!
Johannes-
Here’s a hint as to how you can do this without a “goto”. It looks to
me like you want to keep prompting as long as you haven’t set co1,
right? See if you can fill in the … blanks below to get what you’re
aiming for.
-Alex
co1 = nil
while co1.nil? do
ans1 = gets.chomp
case ans1
when ‘black’
…
when …
…
else
…
end
end
now that we know we got co1, let’s get the next color
if co1 == nil
puts
puts ‘Not acepted, please retype the color’
goto.line 1 <------------------------------ (this was just a wild wild
guess)
end
co1 = false
begin
ans1 = gets.chomp
case ans1
when ‘black’
co1 = 0
when ‘brown’
co1 = 1
else
puts
puts ‘Not acepted, please retype the color’
end
end until co1
puts
puts ‘type in the next color’
ans2 = gets.chomp
— Another way. -----
choice_set = [ %w(black brown), %w(blue green) ]
colors = []
choice_set.each{|choices|
begin
puts “Type one of these colors:”
puts choices
num = choices.index( gets.chomp ) or
puts ‘’, ‘Not acepted, please retype the color’
end until num
colors << num
}
co1 = 0
end
Do you see what i mean? is this possibel to do. Or is there another way
that I can achieve the same effect?
One way is to use the “redo” keyword. However, it only works within a
do-end block. Here’s an example:
$ cat redo.rb
1.times do
print "input: "
ans = gets.chomp
if ans == ‘foo’
puts “bad input: #{ans}”
redo
end
puts “good input: #{ans}”
end
$ ruby redo.rb
input: foo
bad input: foo
input: foo
bad input: foo
input: bar
good input: bar
It is a bit strange to go into a “1.times” loop just so that we can use
the “redo” keyword. (Actually, we could use a while-end block, but that
would be awkward too.) If you like, you can write your own iterator in
place of #times, like so:
def in_redo_context
yield
end
in_redo_context do
print "input: "
ans = gets.chomp
if ans == ‘foo’
puts “bad input: #{ans}”
redo
end
puts “good input: #{ans}”
end
This approach uses a block for each line you want to return to. So this
will start to get messy if you have lots different place to return to,
since you will need nested blocks. In that case, you might want to
consider James’s suggestion of continuations.
Another approach is to use exceptions:
class BadInput < StandardError; end
begin
print "input: "
ans = gets.chomp
if ans == ‘foo’
raise BadInput, “bad input: #{ans}”
end
puts “good input: #{ans}”
rescue BadInput => ex
puts ex.message
retry
end
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.