🐈

[Feature #21126] Hash#freeze 時に #default_proc の値を nil にする提案

2025/02/15に公開

[Feature #21126] Drop default_proc when Hash#freeze is called for better Ractor support

  • default_proc が設定されている Hashfrozen になっていても Ractor 間で送受信ができない
# OK: 問題なく Ractor で扱うことができる
h = { a: 1, b: 2 }
h.freeze

Ractor.new(h) {|h| p h }.take

# NG: freeze されているが default_proc が設定されていると扱うことができない
h = Hash.new {|h, k| h[k] = [] }
h.freeze

# error: 'Ractor.new': allocator undefined for Proc (TypeError)
Ractor.new(h) {|h| p h }.take
  • このような場合に Ractor で利用する前に #default_proc = nil を設定する必要がある
  • これを解消する手段として #freeze した時に自動的に default_proc を無効にする提案
  • Ractor.make_shareable 時にも Hash がネストしている場合に default_proc が設定されている Hash を探す必要がなくなる、みたいなことも利点として挙げられていますね
  • これなんですが下位互換がなくなるという点で Reject されています
    • default_proc が必ずしも Hash を変更するとは限らなかったり #freeze する前と後で挙動が変わったりする
h = Hash.new{|h,k| h[k] = 0}
h[1] # 0
h.freeze
h[1] # 0

# この挙動が変わってしまう
h[2] # Before: FrozenError, After: nil
GitHubで編集を提案

Discussion