2022/03/10 今回の気になった bugs.ruby のチケット

今週はブロックの引数で Hash が分割して受け取れなくなったチケットがありました。

[Misc #18609] keyword decomposition in enumerable (question/guidance)

  • Ruby 3.0 から次のように Hash をキーワード引数で受け取れなくなったというチケット
drafts = [
  {name: 'draft4', mod: :Draft04, image: 'draft4.png'},
  {name: 'draft6', mod: :Draft06, image: 'draft6.jpg'},
]

# Ruby 2.x 系だと Hash をキーワード引数で受け取る事ができた
# Ruby 3.x 系だとキーワード引数の挙動が変わったのでこう書くことができなくなった
drafts.each do |name: , mod: , image: |
end
  • これは Ruby 3.0 で Hash が暗黙的にキーワード引数に変換されなくなった弊害ですね
def test(a:, b:)
end

# Ruby 2.7 => OK: Hash がそのままキーワード引数に変換されていた
# Ruby 3.0 => NG: Hash は暗黙的にキーワード引数に変換されなくなった
test({ a: 1, b: 2 })
  • 上記のように Hash をキーワード引数に渡したい場合は ** を付けることで渡せます
def test(a:, b:)
end

# Ruby 2.7 => OK: Hash をキーワード引数に渡せる
# Ruby 3.0 => OK: Hash をキーワード引数に渡せる
test(**{ a: 1, b: 2 })
module Enumerable
  def each_kw
    each{|v| yield(**v)}
  end
end

drafts.each_kw do |name: , mod: , image: | 
 # ...
end
  • これ、普通に本体にほしい気がする