Module: Collapsium::RecursiveMerge

Extended by:
ViralCapabilities
Included in:
UberHash
Defined in:
lib/collapsium/recursive_merge.rb

Overview

Provides recursive merge functions for hashes.

Constant Summary

Constants included from ViralCapabilities

ViralCapabilities::DEFAULT_ANCESTORS, ViralCapabilities::ENHANCED_MARKER, ViralCapabilities::READ_METHODS, ViralCapabilities::WRITE_METHODS

Constants included from Support::Methods

Support::Methods::BUILTINS, Support::Methods::WRAPPER_HASH

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ViralCapabilities

call_virality, copy_mods, enhance, enhance_array_value, enhance_hash_value, enhance_value, extended, extended, included, included, prepended, prepended, set_ancestors

Methods included from Support::Methods

builtins, loop_detected?, repeated, #resolve_helpers, #wrap_method, wrappers

Class Method Details

.merger(the_self, v1, v2, overwrite) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/collapsium/recursive_merge.rb', line 52

def merger(the_self, v1, v2, overwrite)
  if v1.is_a? Hash and v2.is_a? Hash
    v1 = ViralCapabilities.enhance_value(the_self, v1)
    v2 = ViralCapabilities.enhance_value(the_self, v2)

    # IndifferentAccess has its own idea of which keys are unique, so if
    # we use it, we must consult it.
    keys = (v1.keys + v2.keys).uniq
    if the_self.singleton_class.ancestors.include?(IndifferentAccess)
      keys = IndifferentAccess.unique_keys(keys)
    end
    new_val = ViralCapabilities.enhance_value(the_self, {})
    keys.each do |key|
      v1_inner = v1[key]
      v2_inner = v2[key]
      if not v1_inner.nil? and not v2_inner.nil?
        new_val[key] = RecursiveMerge.merger(the_self, v1_inner, v2_inner,
                                             overwrite)
      elsif not v1_inner.nil?
        # Nothing to do, we have v1[key]
        new_val[key] = v1_inner
      else
        # v2.key?(key) is true
        new_val[key] = v2_inner
      end
    end

    v1.replace(new_val)
    return v1
  elsif v1.is_a? Array and v2.is_a? Array
    return v1 + v2
  end

  if overwrite
    return v2
  end
  return v1
end

Instance Method Details

#recursive_merge(other, overwrite = true) ⇒ Object

Same as ‘dup.recursive_merge!`

Parameters:

  • other (Hash)

    the hash to merge into ‘:self`

  • overwrite (Boolean) (defaults to: true)

    see method description.



47
48
49
# File 'lib/collapsium/recursive_merge.rb', line 47

def recursive_merge(other, overwrite = true)
  return dup.recursive_merge!(other, overwrite)
end

#recursive_merge!(other, overwrite = true) ⇒ Object

Recursively merge ‘:other` into this Hash.

This starts by merging the leaf-most Hash entries. Arrays are merged by addition.

For everything that’s neither Hash or Array, if the ‘:overwrite` parameter is true, the entry from `:other` is used. Otherwise the entry from `:self` is used.

Parameters:

  • other (Hash)

    the hash to merge into ‘:self`

  • overwrite (Boolean) (defaults to: true)

    see method description.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/collapsium/recursive_merge.rb', line 32

def recursive_merge!(other, overwrite = true)
  if other.nil?
    return self
  end

  # We can't call merge! because that will only be invoked for keys that
  # are missing, and default_proc doesn't seem to be used there. So we need
  # to call a custom merge function.
  new_self = RecursiveMerge.merger(self, self, other, overwrite)
  replace(new_self)
end