💬
[Bug #20253] ObjectSpace.define_finalizer に Proc#dup を渡したときのバグ報告
[Bug #20253] Proc.dup
and Proc#clone
don't preserve finalizers
-
ObjectSpace.define_finalizer
に渡したオブジェクトを#dup/clone
した場合はその複製したオブジェクトごとにfinalizer
が呼ばれる-
ObjectSpace.define_finalizer
は指定したオブジェクトが解放されるときに実行される処理を仕込むためのメソッド - ObjectSpace.#define_finalizer (Ruby 3.3 リファレンスマニュアル)
-
def fin(sym)
# obj が解放されるときにこのブロックが呼ばれる
->(obj) { p "#{sym}: #{obj}" }
end
obj = Object.new
ObjectSpace.define_finalizer(obj, fin(:obj))
obj.dup
obj.clone
__END__
output:
"obj: 60"
"obj: 80"
"obj: 100"
- これが
obj
がProc
の場合は呼ばれないというバグ報告
def fin(sym)
# obj が解放されるときにこのブロックが呼ばれる
->(obj) { p "#{sym}: #{obj}" }
end
proc = Proc.new { }
ObjectSpace.define_finalizer(proc, fin(:proc))
# ここでコピーしたオブジェクトの finalizer は呼ばれない
proc.dup
proc.clone
__END__
"proc: 60"
- 他にも
Proc#dup
した場合はインスタンス変数がコピーされない、みたいな挙動もあるみたいですね
def ivar_dup(obj)
obj.instance_variable_set(:@foo, 1)
p [:dup, obj.dup.instance_variable_get(:@foo)]
p [:clone, obj.clone.instance_variable_get(:@foo)]
end
ivar_dup(Object.new)
ivar_dup(Proc.new { })
__END__
output:
[:dup, 1]
[:clone, 1]
[:dup, nil]
[:clone, 1]
- これらの問題は開発版の Ruby 3.4 では修正済み
Discussion