mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
42 lines
1.1 KiB
Ruby
42 lines
1.1 KiB
Ruby
# typed: strict
|
|
# frozen_string_literal: true
|
|
|
|
class Hash
|
|
# Returns a new hash with `self` and `other_hash` merged recursively.
|
|
#
|
|
# ### Examples
|
|
#
|
|
# ```ruby
|
|
# h1 = { a: true, b: { c: [1, 2, 3] } }
|
|
# h2 = { a: false, b: { x: [3, 4, 5] } }
|
|
#
|
|
# h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
|
|
# ```
|
|
#
|
|
# Like with Hash#merge in the standard library, a block can be provided
|
|
# to merge values:
|
|
#
|
|
# ```ruby
|
|
# h1 = { a: 100, b: 200, c: { c1: 100 } }
|
|
# h2 = { b: 250, c: { c1: 200 } }
|
|
# h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val }
|
|
# # => { a: 100, b: 450, c: { c1: 300 } }
|
|
# ```
|
|
def deep_merge(other_hash, &block)
|
|
dup.deep_merge!(other_hash, &block)
|
|
end
|
|
|
|
# Same as {#deep_merge}, but modifies `self`.
|
|
def deep_merge!(other_hash, &block)
|
|
merge!(other_hash) do |key, this_val, other_val|
|
|
if T.unsafe(this_val).is_a?(Hash) && other_val.is_a?(Hash)
|
|
T.unsafe(this_val).deep_merge(other_val, &block)
|
|
elsif block
|
|
yield(key, this_val, other_val)
|
|
else
|
|
other_val
|
|
end
|
|
end
|
|
end
|
|
end
|