Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby's redo method vs while loop

I was reading this question and it got me thinking why one would want to use a while loop when the redo method could be used instead. I can't find any differentiation between the two. I know that the redo method will rerun the block of code, and that while loops will rerun the block of code as long as the conditional is true. Can someone give an example of why you'd want to use one or the other?

like image 461
chell Avatar asked Oct 19 '22 15:10

chell


1 Answers

The redo command restarts the current iteration of a loop (without checking termination conditions in while or advancing iterators in for, for example), you still need a loop of some description (such as a while loop).

That's evidenced by the answer you link to, which contains:

nums = Array.new(5){[rand(1..9), rand(1..9)]}
nums.each do |num1, num2|
  print "What is #{num1} + #{num2}: "
  redo unless gets.to_i == num1 + num2
end

The .each provides the looping structure there and all the redo does is restart that loop (without advancing to the next nums element) if you get the answer wrong.

Now you could actually use a while loop there as the controlling loop, advancing to the next one only if you get it right:

nums = Array.new(5){[rand(1..9), rand(1..9)]}
index = 0
while index < 6 do
    num1 = nums[index][0]
    num2 = nums[index][1]
    print "What is #{num1} + #{num2}: "
    if gets.to_i == num1 + num2 then
        index = index + 1
    end
end

or within the .each itself without redo:

nums = Array.new(5){[rand(1..9), rand(1..9)]}
nums.each do |num1, num2|
    answer = num1 + num2 + 1
    while answer != num1 + num2 do
        print "What is #{num1} + #{num2}: "
        answer = gets.to_i
    end
end

but neither of them are as elegant as the redo solution, which provides a more expressive way of controlling loops, an extension to the usual control you see in other languages, such as continue or break.

like image 56
paxdiablo Avatar answered Oct 22 '22 08:10

paxdiablo