Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyのループ制御をマスターする:redo・retry・nextの使い分けを徹底解説

Rubyには、例外発生後に処理をやり直すためのretryキーワードがあります。しかし、その仲間にあまり知られていないredoというキーワードが存在します。retryがブロック全体を先頭から再実行するのに対し、redoはループの「現在のイテレーション」だけをやり直せる点が特徴です。

redoキーワードの基本

以前のAcademy記事で解説したとおり、retryを使うとブロック内のコードを最初から再実行できます。

begin
  puts "Iteration"
  raise "Error!"
rescue
  retry
end

この例では、コンソールに「Iteration」と出力した直後に例外が発生します。続いてrescue節が実行され、retryによってブロックの先頭から処理がやり直されます。その結果、プログラムは延々とIterationを出力し続けることになります。

redoは、これとよく似た挙動をループの中で実現できるキーワードです。配列などの要素を順番に処理しながら、特定の条件下でのみ処理を再試行したい場合などに特に有用です。

i = 1
loop do
  puts "Iteration #{i}"
  redo if i == 3  # カウンタが進まないため注意
  i += 1
end

このコードの出力結果に注目してください。イテレーション番号が同じままで止まっているはずです。redoは実行位置をループ本体の先頭へ戻すだけで、カウンタの更新やイテレータの評価は再度行われないためです。

ちなみに、retryを使った次のコードもまったく同じ出力になります。

i = 1
begin
  puts "Iteration #{i}"
  raise "Error" if i == 3
  i += 1
rescue
  retry
end

redoはループ内でのリトライ処理の実装にも活用できます。次の例ではジョブのキューを処理しており、各ジョブは:successまたは:failureを返します。失敗した間は同じイテレーションを繰り返し実行し、成功するまで次へ進みません。

jobs.each do |job|
  result = job.run
  redo unless result == :success
end

nextキーワードの基本

現在のイテレーションの先頭に戻るのではなく、「次のイテレーションへ進みたい」場合にはnextを使用します。

(1..5).each do |i|
  puts "Iteration #{i}"
  next if i == 3
  puts "処理を実行しました"
end

この例では、iが3のときだけ後続の処理がスキップされますが、それ以外の場合はイテレーションカウンタがきちんと増え続けます。

多くの場面では、ループの一部を飛ばしたいときに適切なのはnextです。一方、redoが向いているのは、「ループを正確な回数だけ実行したい」「配列をイテレートしながらエラーハンドリングとリトライを行いたい」といったケースです。

まとめ

  • retry:ブロック(begin〜rescue)全体を先頭から再実行する
  • redo:ループの現在のイテレーションだけをやり直す(カウンタは進まない)
  • next:残りの処理をスキップして次のイテレーションへ進む

3つのキーワードの違いを理解しておくと、Rubyでのループ制御やリトライ処理をより柔軟に設計できるようになります。ぜひ実際のコードで試してみてください。

著者プロフィール:Thijs Cadier

最高技術責任者(CTO)兼共同創業者。インフラ整備のために数ヶ月間会社から姿を消すこともある人物です。当社を支える毎日数十億規模のリクエストが正しく処理されるよう見守っています。そして、社内一のドラマーでもあります。

  1. Rackアプリケーションで受信メールを処理する「Incoming!」の使い方

    クライアントから突然電話が… クライアントは、自分のアプリで受信メールを処理したいと言っています。まるでBasecampのように。 「問題ないよ」と思うでしょう。多くのサービスがPOSTリクエスト経由でメールをアプリに送信してくれるのだから、簡単なはずです。本当に? 実は、そう甘くありません。 各サービスは独自のフォーマットを採用しています。パース済みのメールを送ってくるものもあれば、生データを送るものもあります。認証署名付きのサービスもあれば、そうでないものもあります。 この面倒な工程を丸ごとスキップして、標準的(よく知られた)なRubyオブジェクトとして直接扱えたら素敵だと思いま

  2. Rubyで学ぶニューラルネットワーク超入門――思っているほど難しくない!

    この記事では、ニューラルネットワークの基礎と、Rubyを使った実装方法を学びます。人工知能やディープラーニングに興味はあるものの、何から始めればいいのか分からない方にぴったりの内容です。シンプルな例題を通じて、重要な概念をわかりやすく解説していきます。実際にRubyで多層ニューラルネットワークを書くことはほとんどありませんが、コードがシンプルで読みやすいため、内部で何が起きているのかを理解するには最適なアプローチです。まずは少し立ち止まって、私たちがここに至るまでの道のりを見てみましょう。 映画『エクス・マキナ』のワンシーン 『エクス・マキナ(Ex Machina)』は2014年に公開され