ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:121712] [Ruby Feature#15408] Deprecate object_id and _id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
@ 2025-04-23  9:46 ` byroot (Jean Boussier) via ruby-core
  2025-05-08  1:30 ` [ruby-core:121889] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref Dan0042 (Daniel DeLorme) via ruby-core
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 9+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-04-23  9:46 UTC (permalink / raw)
  To: ruby-core; +Cc: byroot (Jean Boussier)

Issue #15408 has been updated by byroot (Jean Boussier).


I opened a PR to finally deprecated `ObjectSpace._id2ref`: https://github.com/ruby/ruby/pull/13157



----------------------------------------
Feature #15408: Deprecate object_id and _id2ref
https://bugs.ruby-lang.org/issues/15408#change-112765

* Author: headius (Charles Nutter)
* Status: Assigned
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [ruby-core:121889] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
  2025-04-23  9:46 ` [ruby-core:121712] [Ruby Feature#15408] Deprecate object_id and _id2ref byroot (Jean Boussier) via ruby-core
@ 2025-05-08  1:30 ` Dan0042 (Daniel DeLorme) via ruby-core
  2025-05-08 14:46 ` [ruby-core:121910] " Eregon (Benoit Daloze) via ruby-core
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 9+ messages in thread
From: Dan0042 (Daniel DeLorme) via ruby-core @ 2025-05-08  1:30 UTC (permalink / raw)
  To: ruby-core; +Cc: Dan0042 (Daniel DeLorme)

Issue #15408 has been updated by Dan0042 (Daniel DeLorme).


The original reason to deprecate `_id2ref` is no longer relevant now that `object_id` is a monotonically-increasing ID. So I don't think it should be deprecated, unless there's some other benefit that wasn't mentioned above.

----------------------------------------
Feature #15408: Deprecate ObjectSpace._id2ref
https://bugs.ruby-lang.org/issues/15408#change-112958

* Author: headius (Charles Nutter)
* Status: Assigned
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [ruby-core:121910] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
  2025-04-23  9:46 ` [ruby-core:121712] [Ruby Feature#15408] Deprecate object_id and _id2ref byroot (Jean Boussier) via ruby-core
  2025-05-08  1:30 ` [ruby-core:121889] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref Dan0042 (Daniel DeLorme) via ruby-core
@ 2025-05-08 14:46 ` Eregon (Benoit Daloze) via ruby-core
  2025-05-08 14:47 ` [ruby-core:121911] " Eregon (Benoit Daloze) via ruby-core
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 9+ messages in thread
From: Eregon (Benoit Daloze) via ruby-core @ 2025-05-08 14:46 UTC (permalink / raw)
  To: ruby-core; +Cc: Eregon (Benoit Daloze)

Issue #15408 has been updated by Eregon (Benoit Daloze).


@Dan0042 It still is, CRuby has to keep a weak map of all objects for which the object_id was asked in case `_id2ref` is used.
That's a big footprint and performance overhead.
It's also impossible to implement this efficiently, as the original description already established.

----------------------------------------
Feature #15408: Deprecate ObjectSpace._id2ref
https://bugs.ruby-lang.org/issues/15408#change-112979

* Author: headius (Charles Nutter)
* Status: Assigned
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [ruby-core:121911] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2025-05-08 14:46 ` [ruby-core:121910] " Eregon (Benoit Daloze) via ruby-core
@ 2025-05-08 14:47 ` Eregon (Benoit Daloze) via ruby-core
  2025-05-08 18:05 ` [ruby-core:121916] " headius (Charles Nutter) via ruby-core
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 9+ messages in thread
From: Eregon (Benoit Daloze) via ruby-core @ 2025-05-08 14:47 UTC (permalink / raw)
  To: ruby-core; +Cc: Eregon (Benoit Daloze)

Issue #15408 has been updated by Eregon (Benoit Daloze).


https://byroot.github.io/ruby/performance/2025/04/26/unlocking-ractors-object-id.html explains the problems of `_id2ref` in details, and how it changed.

----------------------------------------
Feature #15408: Deprecate ObjectSpace._id2ref
https://bugs.ruby-lang.org/issues/15408#change-112980

* Author: headius (Charles Nutter)
* Status: Assigned
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [ruby-core:121916] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2025-05-08 14:47 ` [ruby-core:121911] " Eregon (Benoit Daloze) via ruby-core
@ 2025-05-08 18:05 ` headius (Charles Nutter) via ruby-core
  2025-05-09  3:14 ` [ruby-core:121921] " mame (Yusuke Endoh) via ruby-core
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 9+ messages in thread
From: headius (Charles Nutter) via ruby-core @ 2025-05-08 18:05 UTC (permalink / raw)
  To: ruby-core; +Cc: headius (Charles Nutter)

Issue #15408 has been updated by headius (Charles Nutter).


@Dan0042 I think @Eregon covered what I was going to say, but I'd also like to know **why** you want `_id2ref` to stick around. There's generally better ways (more reliable, easier for VMs to implement) to everything I have seen it used for.

----------------------------------------
Feature #15408: Deprecate ObjectSpace._id2ref
https://bugs.ruby-lang.org/issues/15408#change-112985

* Author: headius (Charles Nutter)
* Status: Assigned
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [ruby-core:121921] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2025-05-08 18:05 ` [ruby-core:121916] " headius (Charles Nutter) via ruby-core
@ 2025-05-09  3:14 ` mame (Yusuke Endoh) via ruby-core
  2025-05-09  6:34 ` [ruby-core:121931] " byroot (Jean Boussier) via ruby-core
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 9+ messages in thread
From: mame (Yusuke Endoh) via ruby-core @ 2025-05-09  3:14 UTC (permalink / raw)
  To: ruby-core; +Cc: mame (Yusuke Endoh)

Issue #15408 has been updated by mame (Yusuke Endoh).


This was discussed at the dev meeting, and @matz agreed to add the deprecation warning.

----------------------------------------
Feature #15408: Deprecate ObjectSpace._id2ref
https://bugs.ruby-lang.org/issues/15408#change-113029

* Author: headius (Charles Nutter)
* Status: Assigned
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [ruby-core:121931] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
                   ` (5 preceding siblings ...)
  2025-05-09  3:14 ` [ruby-core:121921] " mame (Yusuke Endoh) via ruby-core
@ 2025-05-09  6:34 ` byroot (Jean Boussier) via ruby-core
  2025-05-09 20:21 ` [ruby-core:121948] " Dan0042 (Daniel DeLorme) via ruby-core
  2025-05-09 22:01 ` [ruby-core:121949] " headius (Charles Nutter) via ruby-core
  8 siblings, 0 replies; 9+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-05-09  6:34 UTC (permalink / raw)
  To: ruby-core; +Cc: byroot (Jean Boussier)

Issue #15408 has been updated by byroot (Jean Boussier).


I was hoping for a removal timeline, but alright. I'll merge my PR.

----------------------------------------
Feature #15408: Deprecate ObjectSpace._id2ref
https://bugs.ruby-lang.org/issues/15408#change-113041

* Author: headius (Charles Nutter)
* Status: Assigned
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [ruby-core:121948] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
                   ` (6 preceding siblings ...)
  2025-05-09  6:34 ` [ruby-core:121931] " byroot (Jean Boussier) via ruby-core
@ 2025-05-09 20:21 ` Dan0042 (Daniel DeLorme) via ruby-core
  2025-05-09 22:01 ` [ruby-core:121949] " headius (Charles Nutter) via ruby-core
  8 siblings, 0 replies; 9+ messages in thread
From: Dan0042 (Daniel DeLorme) via ruby-core @ 2025-05-09 20:21 UTC (permalink / raw)
  To: ruby-core; +Cc: Dan0042 (Daniel DeLorme)

Issue #15408 has been updated by Dan0042 (Daniel DeLorme).


headius (Charles Nutter) wrote in #note-44:
> I'd also like to know **why** you want `_id2ref` to stick around.

I think that question is backwards. There is no need for any reason to keep existing functionality; backward compatibility should be the default. The question is rather **why** you want `_id2ref` to be deprecated, since the previous reason given was no longer applicable. I don't think the memory usage of the id-to-ref mapping is much of a concern, but I agree that the synchronization issue with Ractors explained in [1] makes it fairly reasonable to deprecate this API. I imagine `_id2ref` *could* be fixed to mostly avoid synchronization by using one lookup table per Ractor + one table for shareable objects, but that sounds like a fairly complex fix and probably not worth the trouble.

[1]https://byroot.github.io/ruby/performance/2025/04/26/unlocking-ractors-object-id.html

----------------------------------------
Feature #15408: Deprecate ObjectSpace._id2ref
https://bugs.ruby-lang.org/issues/15408#change-113068

* Author: headius (Charles Nutter)
* Status: Closed
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [ruby-core:121949] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref
       [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
                   ` (7 preceding siblings ...)
  2025-05-09 20:21 ` [ruby-core:121948] " Dan0042 (Daniel DeLorme) via ruby-core
@ 2025-05-09 22:01 ` headius (Charles Nutter) via ruby-core
  8 siblings, 0 replies; 9+ messages in thread
From: headius (Charles Nutter) via ruby-core @ 2025-05-09 22:01 UTC (permalink / raw)
  To: ruby-core; +Cc: headius (Charles Nutter)

Issue #15408 has been updated by headius (Charles Nutter).


> The question is rather why you want _id2ref to be deprecated

I want it removed, actually! 😀

You have seen all the reasons why it is problematic, but on top of all that it was never intended to be an official API in the first place (I'm not sure where but matz said so in some issue somewhere) which is why it's the only method in the API with a single leading underscore. Since this issue was filed, nearly all of my requirements have been met: 

* object_id is now monotonically increasing.
* WeakMap is an official API.
* Weakref is implemented in terms of WeakMap rather than _id2ref.
* DRb had incorporated a WeakMap implementation. 

With no further need for _id2ref to exist, and numerous reasons to eliminate it, it's time to start that process. 

If you need the functionality of _id2ref, just put objects into a WeakMap with object_id as the key.

----------------------------------------
Feature #15408: Deprecate ObjectSpace._id2ref
https://bugs.ruby-lang.org/issues/15408#change-113069

* Author: headius (Charles Nutter)
* Status: Closed
* Assignee: headius (Charles Nutter)
----------------------------------------
Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected.

As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future.

Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap.

The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently.

The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup.

I propose that both methods should immediately be deprecated for removal in Ruby 3.0.

* They do not do what people expect.
* They cannot reliably do what they claim to do.
* They eventually lead to difficult-to-diagnose bugs in every possible use case.

Put simply, both methods have always been broken in MRI and making them unbroken would render them useless.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-05-09 22:01 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-15408.20181213005326.286@ruby-lang.org>
2025-04-23  9:46 ` [ruby-core:121712] [Ruby Feature#15408] Deprecate object_id and _id2ref byroot (Jean Boussier) via ruby-core
2025-05-08  1:30 ` [ruby-core:121889] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref Dan0042 (Daniel DeLorme) via ruby-core
2025-05-08 14:46 ` [ruby-core:121910] " Eregon (Benoit Daloze) via ruby-core
2025-05-08 14:47 ` [ruby-core:121911] " Eregon (Benoit Daloze) via ruby-core
2025-05-08 18:05 ` [ruby-core:121916] " headius (Charles Nutter) via ruby-core
2025-05-09  3:14 ` [ruby-core:121921] " mame (Yusuke Endoh) via ruby-core
2025-05-09  6:34 ` [ruby-core:121931] " byroot (Jean Boussier) via ruby-core
2025-05-09 20:21 ` [ruby-core:121948] " Dan0042 (Daniel DeLorme) via ruby-core
2025-05-09 22:01 ` [ruby-core:121949] " headius (Charles Nutter) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).