🦔

[Feature #15408] ObjectSpace._id2ref を削除するチケット

に公開

[Feature #15408] Deprecate ObjectSpace._id2ref

  • NOTE: このチケットが起票されたのは6年前
  • Ruby では任意のオブジェクトから一意となるような値を取得する #object_id とその値から元のオブジェクトを取得できる ObjectSpace.#_id2ref 存在しています
a = "hoge"

# 何かしら一意となる値を返す
p a.object_id # => 16

# 値が同じだからといって同じ object_id とは限らない
b = "hoge"
p b.object_id # => 24

# ObjectSpace._id2ref から object_id を元にして元のオブジェクトを参照することもできる
p ObjectSpace._id2ref(a.object_id) #=> "hoge"
  • これなんですが前提として #object_id が一意である必要があるんですが実際には『ガベージコレクションされたあとにはその限りではない』らしいです
    • ただ、この話なんですがチケットが起票された6年前はそうだったみたいなんですが現状だと #object_id の割当の仕組みが変わっているらしく問題にならなくなったみたいですね
    • https://bugs.ruby-lang.org/issues/15408#note-41
  • なのでこのチケットでは #object_id とそれを利用する ObjectSpace.#_id2ref を削除する、という旨のチケットになっています
  • 議論自体は長いので内容は省略するんですが6年前の時点では以下の点で matz が同意したみたいですね
  • また、当時の標準ライブラリで ObjectSpace.#_id2ref を利用しているのは DRb だけみたいでそちらは ObjectSpace::WeakMap を利用することで回避したみたいですね
  • って、いうのが6年前の話なんですが実際にはまだ ObjectSpace.#_id2ref は削除されずにそのまま利用できる状態でした
  • これが Ruby 3.5 からは『 ObjectSpace.#_id2ref を使用すると警告が表示される』ようになります
    • -W:deprecated がついているときのみ警告が出力される
Warning[:deprecated] = true

a = "hoge"

# 何かしら一意となる値を返す
p a.object_id # => 16

# ObjectSpace._id2ref から object_id を元にして元のオブジェクトを参照することもできる
p ObjectSpace._id2ref(a.object_id) #=> "hoge"
# Ruby 3.4 => no warning
# Ruby 3.5 => warning: ObjectSpace._id2ref is deprecated
  • 将来的に ObjectSpace.#_id2ref は削除されると思いますがそれがいつなのかはまだ決まってないみたいですね
  • ちなみに _id2ref は唯一アンダースコアから始まるメソッドらしい
GitHubで編集を提案

Discussion