Class: Hash
Instance Method Summary collapse
-
#can_merge?(other) ⇒ Boolean
Checks if other can be merged with this hash.
-
#deep_dup ⇒ Hash
Creates deep copy of hash with all nested structures.
-
#deep_merge!(other, array_strategy: nil) ⇒ self
Deep merges other hash into self, modifying receiver.
Methods included from IS::Deep
Instance Method Details
#can_merge?(other) ⇒ Boolean
Checks if other can be merged with this hash.
92 93 94 |
# File 'lib/is-deep.rb', line 92 def can_merge?(other) other.is_a?(Hash) || other.respond_to?(:to_hash) end |
#deep_dup ⇒ Hash
Creates deep copy of hash with all nested structures.
Handles circular references correctly. Preserves default values and default_proc if present.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/is-deep.rb', line 20 def deep_dup visited_wrap do |visited| self_id = self.object_id return visited[self_id] if visited.has_key?(self_id) result = {} visited[self_id] = result if self.default_proc != nil result.default_proc = self.default_proc elsif self.default != nil result.default = self.default end self.each do |key, value| id = value.object_id result[key] = if visited.has_key?(id) visited[id] elsif value.respond_to?(:deep_dup) visited[id] = value.deep_dup elsif value.respond_to?(:dup) visited[id] = value.dup else visited[id] = value end end result end end |
#deep_merge!(other, array_strategy: nil) ⇒ self
Deep merges other hash into self, modifying receiver.
Recursively merges nested hashes. For conflicting values where old value responds to #can_merge? and returns true, attempts recursive merge. Otherwise replaces with new value.
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 |
# File 'lib/is-deep.rb', line 60 def deep_merge! other, array_strategy: nil visited_wrap do |visited| id = self.object_id return self if visited.has_key?(id) visited[id] = self source = if other.is_a?(Hash) other elsif other.respond_to?(:to_hash) other.to_hash else raise ArgumentError, "Unsupported type of source: (#{ other.class })", caller_locations end source.each do |key, value| if self.has_key?(key) old = self[key] if old.respond_to?(:can_merge?) && old.can_merge?(value) old.deep_merge! value, array_strategy: array_strategy else self[key] = value end else self[key] = value end end self end end |