
Issue #21028 has been updated by osyoyu (Daisuke Aritomo). I have been relying a lot on @mame 's snippet when programming with Ractors. It has been very useful to find why a library function / constant violates the rules of Ractors. I have opened a pull request to add `ObjectSpace#find_paths_to_unshareable_objects`, a version of this method which returns all unshareable objects which can be traced from `obj`. https://github.com/ruby/ruby/pull/13963 ```ruby require 'objspace' def find_paths_to_unshareable_objects(obj) return to_enum(__method__, obj) if !block_given? queue = [[obj, []]] visited = Set.new while current = queue.shift current_obj, current_path = current visited.add(current_obj.object_id) if !Ractor.shareable?(current_obj) yield current_path + [current_obj] ObjectSpace.reachable_objects_from(current_obj).each do |reachable| if !reachable.is_a?(ObjectSpace::InternalObjectWrapper) && !visited.include?(reachable.object_id) queue.push([reachable, current_path + [current_obj]]) end end end end end # Paths to all unshareable objects are yielded pp *find_paths_to_unshareable_objects([1, 2, 3, +"str", { :key => -> {} }]) #=> [[1, 2, 3, "str", {key: #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>}]] #=> [[1, 2, 3, "str", {key: #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>}], "str"] #=> [[1, 2, 3, "str", {key: #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>}], {key: #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>}] #=> [[1, 2, 3, "str", {key: #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>}], {key: #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>}, #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>] #=> [[1, 2, 3, "str", {key: #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>}], {key: #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>}, #<Proc:0x00007f22b7a5e598 rac.rb:25 (lambda)>, main] ``` ---------------------------------------- Feature #21028: Method for finding why an object isn't Ractor shareable https://bugs.ruby-lang.org/issues/21028#change-114151 * Author: tenderlovemaking (Aaron Patterson) * Status: Feedback * Assignee: tenderlovemaking (Aaron Patterson) ---------------------------------------- `Ractor.shareable?` is easy to use, but if it returns false I would like to be able to figure out what object is causing the data structure to _not_ be Ractor shareable. The context is that I'm trying to make some complex data structures in Rails deeply frozen. If they are deeply frozen they _should_ be Ractor shareable, but `Ractor.shareable?` is returning `false` and it's hard for me to figure out _why_. I would like a method that would either return all unshareable references, or a method that takes a block and unshareable references are yielded to the block. A method like `Ractor.unshareable_references?` or maybe `Ractor.shareable?(obj) { |not_shareable_obj| }` would be very helpful for discovering why an object is not shareable. Thanks! -- https://bugs.ruby-lang.org/