Skip to content

Commit

Permalink
Merge nil values or keep the original via an option
Browse files Browse the repository at this point in the history
For some people, it's unexpected that explicitly merging in a nil will
not overwrite an existing value.
`DeepMerge::deep_merge({:a => nil}, {:a => 1})`

Currently, we retain the 1 value.
My expectation is we'd get a nil value.

Since changing this is a change in behavior, and possibly not desirable,
I'm exposing an option to opt-in to this new behavior.

Note, this is related to danielsdeleo#20 and can be confusing to see the difference.
This commit handles merging a nil value into an existing destination via
an option.
PR danielsdeleo#20 handles NOT merging a value into an already nil destination.
  • Loading branch information
jrafanie committed Apr 21, 2017
1 parent 989b2df commit 5327c12
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
4 changes: 3 additions & 1 deletion lib/deep_merge/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,12 @@ def self.deep_merge!(source, dest, options = {})
extend_existing_arrays = options[:extend_existing_arrays] || false
# request that arrays keep duplicate elements
keep_array_duplicates = options[:keep_array_duplicates] || false
# request that nil values are discarded
discard_nil_values = options.fetch(:discard_nil_values, true)

di = options[:debug_indent] || ''
# do nothing if source is nil
return dest if source.nil?
return dest if discard_nil_values && source.nil?
# if dest doesn't exist, then simply copy source to it
if !(dest) && overwrite_unmergeable
dest = source; return dest
Expand Down
19 changes: 17 additions & 2 deletions test/test_deep_merge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,22 @@ def test_deep_merge
DeepMerge::deep_merge!(hash_src, hash_dst, {:keep_array_duplicates => true})
assert_equal({"item" => ["1", "2", "2", "3"]}, hash_dst)



# discard nil value by default
hash_src = {"item" => nil}
hash_dst = {"item" => 'existing'}
DeepMerge::deep_merge!(hash_src, hash_dst)
assert_equal({"item" => 'existing'}, hash_dst)

# discard nil value via discard_nil_values => true
hash_src = {"item" => nil}
hash_dst = {"item" => 'existing'}
DeepMerge::deep_merge!(hash_src, hash_dst, {:discard_nil_values => true})
assert_equal({"item" => 'existing'}, hash_dst)

# keep nil value via discard_nil_values => false
hash_src = {"item" => nil}
hash_dst = {"item" => 'existing'}
DeepMerge::deep_merge!(hash_src, hash_dst, {:discard_nil_values => false})
assert_equal({"item" => nil}, hash_dst)
end # test_deep_merge
end

0 comments on commit 5327c12

Please sign in to comment.