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 に答える