Techioz Blog

Ruby 3 でのハッシュの分割

概要

Ruby 2 では次のことができます。

my_hash = {a: {aa: 1, ab: 2, ac: 3}}

my_hash.each do |key, aa:, ab: 4, **|
  puts key
  puts aa
  puts ab
end

Ruby 3 では、これによりキーワード :aa、:ab が欠落するようになりました。 Ruby 3 でこのようなコードをリファクタリングする最善の方法は何でしょうか?

次のようなものは、デフォルト値の設定をサポートしていないため機能しません。

my_hash.each do |key, values|
  values in {aa: aa, ab: ab}
end

私が考える最善の方法は、既存のコードをラッパーに入れることです。

lambda = ->(key, aa:, ab: 4, **) do
  puts key
  puts aa
  puts ab
end

my_hash.each do |key, values|
  lambda.call(key, **values)
end

もっと良い選択肢はありますか?

解決策

ハッシュをキーワード引数に変換する方法が思いつきません。

しかし、ハッシュをそのまま、つまりキーをキーワードのように扱わずに使用してはどうでしょうか?実際のコードがより複雑でない限り、fetch はあなたが望むことを行うようです。

my_hash = {a: {aa: 1, ab: 2, ac: 3}}

my_hash.each do |key, values|
  puts key
  puts values.fetch(:aa)
  puts values.fetch(:ab, 4)
end

上記は Ruby 2 と 3 の両方で正常に動作します。例と同様に、:aa が欠落している場合はエラーが発生し、:ab が欠落している場合はデフォルト値の 4 が使用されます。