Class: CoreLibrary::DeepCloneUtils

Inherits:
Object
  • Object
show all
Defined in:
lib/apimatic-core/utilities/deep_clone_utils.rb

Overview

DeepCloneUtils provides utility methods for performing deep copies of various Ruby objects.

It supports deep copying of arrays (including nested arrays), hashes (with nested keys/values), and arbitrary objects. For custom objects, it attempts to use the ‘deep_copy` method if defined; otherwise, it falls back to using `dup` with error handling.

The implementation also keeps track of already visited objects using identity-based hashing to safely handle circular references and avoid redundant cloning.

Example usage:

original = { foo: [1, 2, { bar: 3 }] }
copy = CoreLibrary::DeepCloneUtils.deep_copy(original)

copy[:foo][2][:bar] = 99
puts original[:foo][2][:bar] # => 3 (remains unchanged)

Class Method Summary collapse

Class Method Details

.deep_copy(value, visited = {}.compare_by_identity) ⇒ Object

Deep copy any value with support for arrays, hashes, and custom deep_copy methods.

Parameters:

  • value (Object)

    The value to deeply clone.

  • visited (Hash) (defaults to: {}.compare_by_identity)

    A hash that tracks already visited objects to handle cycles.

Returns:

  • (Object)

    A deep copy of the input value.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/apimatic-core/utilities/deep_clone_utils.rb', line 24

def deep_copy(value, visited = {}.compare_by_identity)
  return value if primitive?(value)
  return visited[value] if visited.key?(value)

  result = case value
           when Array
             deep_copy_array(value, visited)
           when Hash
             deep_copy_hash(value, visited)
           else
             deep_copy_object(value)
           end

  visited[value] = result
  result
end

.deep_copy_array(array, visited = {}.compare_by_identity) ⇒ Array

Deep copy a plain array (supports n-dimensional arrays).

Parameters:

  • array (Array)

    The array to deeply clone.

  • visited (Hash) (defaults to: {}.compare_by_identity)

    Identity hash to track visited objects.

Returns:

  • (Array)

    A deep copy of the array.



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/apimatic-core/utilities/deep_clone_utils.rb', line 46

def deep_copy_array(array, visited = {}.compare_by_identity)
  return nil if array.nil?
  return array if primitive?(array)

  visited[array] = array_clone = []

  array.each do |item|
    array_clone << deep_copy(item, visited)
  end

  array_clone
end

.deep_copy_hash(hash, visited = {}.compare_by_identity) ⇒ Hash

Deep copy a hash (map), including nested maps.

Parameters:

  • hash (Hash)

    The hash to deeply clone.

  • visited (Hash) (defaults to: {}.compare_by_identity)

    Identity hash to track visited objects.

Returns:

  • (Hash)

    A deep copy of the hash.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/apimatic-core/utilities/deep_clone_utils.rb', line 64

def deep_copy_hash(hash, visited = {}.compare_by_identity)
  return nil if hash.nil?
  return hash if primitive?(hash)

  visited[hash] = hash_clone = {}

  hash.each do |key, value|
    # Keys are usually immutable, but still cloned for safety
    key_copy = primitive?(key) ? key : deep_copy(key, visited)
    hash_clone[key_copy] = deep_copy(value, visited)
  end

  hash_clone
end