如何从(yield)块中的代码中打破循环?

时间:2011-01-18 17:13:31

标签: ruby

jobs.each do | job |
  msg job.name do
    break if stop_all_jobs?
    job.run!
  end
end   

def msg(msg, &block)
  puts 'START ' + msg
  yield
  puts 'END ' + msg
end

在上面的例子中,break没有像预期的那样突破循环。它只会突破msg代码块。

这看起来有点奇怪,但我想它是基于上下文的,那就是说,如何从yield ed代码块中的代码中突破循环?

2 个答案:

答案 0 :(得分:2)

一种方法是使用throw/catch。不,不是例外,Ruby有一个单独的流控制功能,有点像异常,没有所有开销(虽然我必须承认我不确定没有任何开销使用它):

catch :stop_all_jobs do
  msg job.name do
    throw :stop_all_jobs if stop_all_jobs?
    job.run!
  end
end

您甚至可以将值作为第二个参数传递给throw,这将是catch块的结果。

当然,可能更具可读性的解决方案是将代码打包在方法中并使用return代替break。但这不会那么有趣。

答案 1 :(得分:-2)

使用next代替break