🐈
[Feature #21126] Hash#freeze 時に #default_proc の値を nil にする提案
[Feature #21126] Drop default_proc when Hash#freeze is called for better Ractor support
-
default_proc
が設定されているHash
はfrozen
になっていても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
Discussion