🔖

【bugs.ruby Advent Calender】ObjectSpace.define_finalizer のバグ報告【3日目】

2024/12/03に公開

bugs.ruby Advent Calender 3日目の記事です。

これはなに

今年1年間通してみてきた bugs.ruby のチケットの中から気になったものを1つずつ取り上げていく Advent Calender です。
取り上げるチケットは基本的にこのブログで取り上げたものになります。
記事のまとめは ここを参照 してください。

[Bug #20253] Proc.dup and Proc#clone don't preserve finalizers

ObjectSpace.define_finalizer は指定したオブジェクトが #dup/clone したときに設定した Proc が呼び出されます。

callback = proc { |obj|
  pp "#{obj}"
}

obj = "homu"
ObjectSpace.define_finalizer(obj, callback)

# obj を clone したときに callback が呼ばれる
obj.clone

これが objProc のときに callback が呼ばれない、というバグ報告になります。

callback = proc { |obj|
  pp "#{obj}"
}

obj = proc {}
ObjectSpace.define_finalizer(obj, callback)

# obj を clone したときに callback が呼ばれる
obj.clone

この問題はすでに修正済みで Ruby 3.3.5 にもバックポートされています。

個人的に面白かったのがこのチケットの中で『 Proc オブジェクトを #dup したときにインタンス変数がコピーされない』という点も指摘されていました。

obj = proc {}
obj.instance_variable_set(:@foo, 1)

# #dup だとインスタンス変数はコピーされない
pp obj.dup.instance_variable_get(:@foo)   # => nil

# #clone だとインスタンス変数もコピーされる
pp obj.dup.instance_variable_get(:@foo)   # => 1

何がどうなってこういうバグが発生しているのか…。
この問題も修正されており Ruby 3.3.5 にもバックポートされています。

関連

GitHubで編集を提案

Discussion