class Backports::Ractor::Cloner

def clone_deeper(obj)

nothing is yielded
If no deep copy is needed, `obj` is returned and
Yields a deep copy.
def clone_deeper(obj)
 obj if Ractor.ractor_shareable_self?(obj, false) { false }
 = process(obj) do |r|
_contents(r)
 obj unless result
result if block_given?

def copy_contents(obj)

modifies in place `obj` by calling `deep clone` on its contents
def copy_contents(obj)
bj
:Hash
bj.default
one_deeper(obj.default) do |copy|
obj.default = copy
d
transform_keys! { |key| clone_deeper(key) }
transform_values! { |value| clone_deeper(value) }
:Array
map! { |item| clone_deeper(item) }
:Struct
each_pair do |key, item|
one_deeper(item) { |copy| obj[key] = copy }
stance_variables.each do |var|
e_deeper(obj.instance_variable_get(var)) do |copy|
j.instance_variable_set(var, copy)

def deep_clone(obj)

def deep_clone(obj)
  return obj if Ractor.ractor_shareable_self?(obj, false) { false }
  new.deep_clone(obj)
end

def deep_clone(obj)

def deep_clone(obj)
  result = process(obj) do |r|
    copy_contents(r)
  end
  return result if result
  Ractor.ractor_mark_set_shareable(@processed)
  obj
end

def initialize

def initialize
  @processed = {}.compare_by_identity
  @changed = nil
end

def process(obj)

Returns the deep copy, or `false` if no deep copy is needed
Yields if `obj` is a new structure
def process(obj)
ssed.fetch(obj) do
r recursive structures, assume that we'll need a duplicate.
 that's not the case, we will have duplicated the whole structure
r nothing...
cessed[obj] = result = obj.dup
ged = track_change { yield result }
rn false if obj.frozen? && !changed
nged = true
lt.freeze if obj.frozen?
lt

def track_change

returns if the block called `deep clone` and that the deep copy was needed
def track_change
 @changed
ed = false
ed
ed = prev