このマニュアルは既にメンテナンスが終了したバージョンの Ruby を対象としています。 最新版のマニュアルへ

Ruby 3.0 リファレンスマニュアル

instance method Hash#each

each {|key, value| ... } -> self[permalink][rdoc][edit]
each_pair {|key, value| ... } -> self
each -> Enumerator
each_pair -> Enumerator

ハッシュのキーと値を引数としてブロックを評価します。

反復の際の評価順序はキーが追加された順です。ブロック付きの場合 self を、無しで呼ばれた場合 Enumerator を返します。

each_pair は each のエイリアスです。

{:a=>1, :b=>2}.each {|a| p a}
#=> [:a, 1]
#   [:b, 2]

{:a=>1, :b=>2}.each {|k, v| p [k, v]}
#=> [:a, 1]
#   [:b, 2]

p({:a=>1, :b=>2}.each_pair)  # => #<Enumerator: {:a=>1, :b=>2}:each_pair>

Ruby 3.0 から、ブロックには常に [key, value] という2要素の配列が1つの引数として yield されるようになりました。通常のブロックでは {|k, v| ... } のように複数の仮引数を書けば配列が自動的に分解されるため、これまでと同様にキーと値を別々の引数として受け取れます。

一方、& を使って lambda や Method オブジェクトをブロックとして渡す場合はこの自動分解が行われません。そのため、2引数の lambda(->(k, v) { ... })を渡すコードは、 Ruby 2.7 までは動作していましたが、Ruby 3.0 以降は ArgumentError になります。 1引数で配列として受け取るか、->((k, v)) { ... } のように仮引数を括弧で囲んで分解してください。

# Ruby 2.7 まではこの書き方でも動作していましたが、Ruby 3.0 以降は ArgumentError になります
{foo: 100}.each(&->(k, v) { p [k, v] })
# ~> ArgumentError

# 1引数で配列として受け取る
{foo: 100}.each(&->(pair) { p pair })
#=> [:foo, 100]

# 仮引数を括弧で囲んで分解する
{foo: 100}.each(&->((k, v)) { p [k, v] })
#=> [:foo, 100]

[SEE_ALSO] Hash#each_key,Hash#each_value