diff options
author | Joe Marty <jmarty@iexposure.com> | 2016-12-13 14:43:47 -0600 |
---|---|---|
committer | Daniel Doubrovkine (dB.) @dblockdotorg <dblock@dblock.org> | 2016-12-13 15:43:47 -0500 |
commit | 199d816bc0865d4276a1b6db669ef9f3a2fedfc1 (patch) | |
tree | 4156626d394cf98c30590bb14d2eab013364d084 | |
parent | fb7dd06af5189ef483f0a466d12ab52f2838b86f (diff) | |
download | hashie-199d816bc0865d4276a1b6db669ef9f3a2fedfc1.tar.gz |
Fix #385 - deep merge by reference bug (#386)
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | lib/hashie/extensions/deep_merge.rb | 2 | ||||
-rw-r--r-- | spec/hashie/extensions/deep_merge_spec.rb | 9 |
3 files changed, 10 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ce04bb7..dd15125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ scheme are considered to be bugs. ## [Unreleased][unreleased] +* [#386](https://github.com/intridea/hashie/pull/386): Fix for #385: Make `deep_merge` always `deep_dup` nested hashes before merging them in so that there are no shared references between the two hashes being merged. - [@mltsy](https://github.com/mltsy). + [3.4.7]: https://github.com/intridea/hashie/compare/v3.4.6...master ### Added diff --git a/lib/hashie/extensions/deep_merge.rb b/lib/hashie/extensions/deep_merge.rb index df0887d..5d8fe34 100644 --- a/lib/hashie/extensions/deep_merge.rb +++ b/lib/hashie/extensions/deep_merge.rb @@ -26,7 +26,7 @@ module Hashie if hash.key?(k) && block_given? block.call(k, hash[k], v) else - v + v.respond_to?(:deep_dup) ? v.deep_dup : v end end end diff --git a/spec/hashie/extensions/deep_merge_spec.rb b/spec/hashie/extensions/deep_merge_spec.rb index 0815c15..aec2d7d 100644 --- a/spec/hashie/extensions/deep_merge_spec.rb +++ b/spec/hashie/extensions/deep_merge_spec.rb @@ -14,8 +14,8 @@ describe Hashie::Extensions::DeepMerge do context 'without &block' do let(:h1) { subject.new.merge(a: 'a', a1: 42, b: 'b', c: { c1: 'c1', c2: { a: 'b' }, c3: { d1: 'd1' } }) } - let(:h2) { { a: 1, a1: 1, c: { c1: 2, c2: 'c2', c3: { d2: 'd2' } } } } - let(:expected_hash) { { a: 1, a1: 1, b: 'b', c: { c1: 2, c2: 'c2', c3: { d1: 'd1', d2: 'd2' } } } } + let(:h2) { { a: 1, a1: 1, c: { c1: 2, c2: 'c2', c3: { d2: 'd2' } }, e: { e1: 1 } } } + let(:expected_hash) { { a: 1, a1: 1, b: 'b', c: { c1: 2, c2: 'c2', c3: { d1: 'd1', d2: 'd2' } }, e: { e1: 1 } } } it 'deep merges two hashes' do expect(h1.deep_merge(h2)).to eq expected_hash @@ -25,6 +25,11 @@ describe Hashie::Extensions::DeepMerge do h1.deep_merge!(h2) expect(h1).to eq expected_hash end + + it 'merges new nested hash entries by value, not by reference' do + h1.deep_merge!(h2) + expect { h1[:e][:e1] = 'changed' }.not_to change { h2[:e][:e1] } + end end context 'with &block' do |