Ruby の for と each の違い

Stewart Nguyen 2023年1月30日
  1. Ruby の Array#each
  2. Ruby の for..in ループ
Ruby の for と each の違い

Ruby では、Array#eachfor..in の両方を使用して配列を反復処理できます。ただし、この 2つには大きな違いがあります。

Ruby の Array#each

Ruby の Array#each メソッドは、配列内の個々のアイテムを反復処理するための最も簡単で広く使用されているメソッドです。

each はクラス Array の組み込みメソッドであり、Ruby 配列の項目を反復処理するための最も一般的な方法です。

each はパラメータとしてブロックを取り、現在のアイテムを返します。

[1, 2, 3].each { |n| puts n }

出力:

1
2
3

Ruby の for..in ループ

他のほとんどのプログラミング言語と同様に、Ruby には配列をループするための for ステートメントがあります。

for の後には、現在の要素としての変数と反復配列が続きます。

for n in [1, 2, 3]
  puts n
end

出力:

1
2
3

内部的には、Array#eachfor..in はほぼ同じことを行います。ただし、重大な問題を引き起こす可能性のある小さな違いが 1つあります。

[1, 2, 3].each { |n| n }
puts n

出力:

NameError (undefined local variable or method `n' for main:Object)

コードサンプル:

for n in [1, 2, 3]
 n
end
puts n

出力:

3

Array#each の後に n を出力しようとするとエラーが発生しますが、for ループの後に 3 が出力されます。

どうしたの?

for..in が実行される前に、変数 n が事前に定義されています。ブロックが完了した後も、ブロックの外側に表示されたままになります。

つまり、for ループは次のようになります。

n = nil
[1, 2, 3].each { |i| n = i }
puts n

出力:

3

Array#each の場合、変数 n はブロック {| n |内で定義されます。puts n} であるため、ブロックのスコープ外には表示されません。

for ループを使用すると、副作用として余分な変数が導入され、イライラする問題が発生する可能性があります。その結果、for..in よりも Array#each が優先されます