重试在控制流中不起作用

时间:2014-01-28 18:56:16

标签: ruby

我正在尝试执行以下代码:

animals = %w(dog cat horse goat snake frog)
count = 0

for animal in animals
    puts "The current animal is #{animal}"
    break if count == 10
    count += 1
    retry if animal == 'horse'
end

当我尝试在IRB上执行文件时,我得到以下输出:

2.0.0-p247 :001 > load 'loopexit.rb'
SyntaxError: loopexit.rb:19: Invalid retry
    from loopexit.rb
2.0.0-p247 :002 >

有人可以告诉我这里可能有什么问题吗?

4 个答案:

答案 0 :(得分:3)

rescue子句中,retry导致Ruby返回到封闭代码的顶部(begin关键字,或方法或块的顶部)并尝试再次执行代码

但您需要使用next。它会无条件地将迭代器whileuntil块碰到 next 迭代,而不会执行块中剩余的任何内容。

retry不能在循环中使用。

您可以编写如下代码:

for animal in animals
    next if animal == 'horse'
    puts "The current animal is #{animal}"
    break if count == 10
    count += 1
end

答案 1 :(得分:1)

因为Ruby 1.9 retry不能再用于循环了。

它曾经跳转到第一次迭代的开始。有时您可能仍会找到引用Ruby 1.8的书籍和教程,但不再支持它。

循环中的有效关键字是

  • next跳转到下一次迭代的开始
  • redo跳转到当前迭代的开头
  • break结束循环

答案 2 :(得分:0)

使用next代替retry,因为您想跳过当前的迭代。 retry用于例外,而不是循环。

但是你的逻辑中也有错误:你想要快速跳过迭代,因为你知道动物是horse,所以你应该移动next循环顶部的语句:

for animal in animals
    next if animal == 'horse'
    puts "The current animal is #{animal}"
    break if count == 10
    count += 1
end

答案 3 :(得分:0)

这并不能保证完全符合您的要求,但它是用类似Ruby的(并且对我来说,更明智的)方式编写的:

animals = %w(dog cat horse goat snake frog)

animals.each_with_index do |animal, i|
  next if animal == 'horse'
  puts "The current animal is #{ animal }"
  break if i == 10
end

我们通常不使用for循环。这样做会暴露中间变量animal,这会不必要地污染变量空间。相反,使用each,变量animal仅限于do块,因此不会浪费可变空间。

each_with_index将计数器作为参数传递给块,这样可以很容易地知道已经看到了多少,或者当前的索引值是什么。

当然,break if i == 10永远不会执行,除非animals的元素数超过10个。