diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-05-07 17:59:19 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-05-07 18:03:03 -0300 |
commit | 6b2f37741cf4f55c6237f0d8cde45c9caea4cf12 (patch) | |
tree | 4a25c448a2f5a2937ca70dd6d4f644844d996886 /activesupport/lib | |
parent | 73fb39b6faa9de593ae75ad4e3b8e065ea0e53af (diff) | |
parent | 0438134476b05d14dffbb28f84eac582bd3cfa8f (diff) | |
download | rails-6b2f37741cf4f55c6237f0d8cde45c9caea4cf12.tar.gz rails-6b2f37741cf4f55c6237f0d8cde45c9caea4cf12.tar.bz2 rails-6b2f37741cf4f55c6237f0d8cde45c9caea4cf12.zip |
Merge pull request #12746 from coreyward/master
Fix Hash#deep_merge bug and improve documentation — resolves #12738
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/core_ext/hash/deep_merge.rb | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb index dc86c92003..763d563231 100644 --- a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb +++ b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb @@ -1,27 +1,38 @@ class Hash # Returns a new hash with +self+ and +other_hash+ merged recursively. # - # h1 = { x: { y: [4, 5, 6] }, z: [7, 8, 9] } - # h2 = { x: { y: [7, 8, 9] }, z: 'xyz' } + # h1 = { a: true, b: { c: [1, 2, 3] } } + # h2 = { a: false, b: { x: [3, 4, 5] } } # - # h1.deep_merge(h2) # => {x: {y: [7, 8, 9]}, z: "xyz"} - # h2.deep_merge(h1) # => {x: {y: [4, 5, 6]}, z: [7, 8, 9]} - # h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) } - # # => {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]} + # 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: + # + # 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) - other_hash.each_pair do |k,v| - tv = self[k] - if tv.is_a?(Hash) && v.is_a?(Hash) - self[k] = tv.deep_merge(v, &block) + other_hash.each_pair do |current_key, other_value| + this_value = self[current_key] + + self[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash) + this_value.deep_merge(other_value, &block) else - self[k] = block && tv ? block.call(k, tv, v) : v + if block_given? && key?(current_key) + block.call(current_key, this_value, other_value) + else + other_value + end end end + self end end |