0

我有一个自定义异常,我希望在执行该方法导致错误时多次引发和救援。我知道它最终会导致无异常结果。

使用 begin/rescue/end 似乎是在抛出异常并调用救援块时,如果再次抛出异常,程序将离开 begin/rescue/end 块并且错误结束程序。如何保持程序运行直到达到正确的结果?另外,我对正在发生的事情的看法是否不正确?

这基本上就是我想要发生的事情(但显然尽可能使用 DRY 的代码......这段代码只是为了说明而不是我要实现的)。

ships.each do |ship|
  begin
    orientation = rand(2) == 1 ? :vertical : :horizontal
    cell_coords = [rand(10), rand(10)] 
    place_ship(ship, orientation, cell_coords)
  rescue OverlapError  #if overlap error happens twice in a row, it leaves?
    orientation = rand(2) == 1 ? :vertical : :horizontal
    cell_coords = [rand(10), rand(10)] 
    place_ship(ship, orientation, cell_coords)
  rescue OverlapError
    orientation = rand(2) == 1 ? :vertical : :horizontal
    cell_coords = [rand(10), rand(10)] 
    place_ship(ship, orientation, cell_coords)
  rescue OverlapError
    orientation = rand(2) == 1 ? :vertical : :horizontal
    cell_coords = [rand(10), rand(10)] 
    place_ship(ship, orientation, cell_coords)
  #keep rescuing until the result is exception free
  end
end
4

1 回答 1

3

您可以使用retry

ships.each do |ship|
  begin
    orientation = rand(2) == 1 ? :vertical : :horizontal
    cell_coords = [rand(10), rand(10)] 
    place_ship(ship, orientation, cell_coords)
  rescue OverlapError  #if overlap error happens twice in a row, it leaves?
    retry
  end
end

无论如何,我不得不说你不应该使用异常作为控制流。我会推荐你​​,如果place_ship预计会失败,它应该返回true/false结果,并且你应该将代码包含在标准do while循环中。

于 2013-07-21T21:54:14.760 回答