From 98dbc146f9c01fc7811cc863b7219a83ee257bdb Mon Sep 17 00:00:00 2001 From: dtaniwaki Date: Wed, 11 Mar 2015 12:22:01 -0700 Subject: [PATCH 1/2] Skip merging if the destination is nil --- lib/deep_merge/core.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/deep_merge/core.rb b/lib/deep_merge/core.rb index 374ae77..a6cba26 100644 --- a/lib/deep_merge/core.rb +++ b/lib/deep_merge/core.rb @@ -92,9 +92,13 @@ def self.deep_merge!(source, dest, options = {}) source.each do |src_key, src_value| if dest.kind_of?(Hash) puts "#{di} looping: #{src_key.inspect} => #{src_value.inspect} :: #{dest.inspect}" if merge_debug - if dest[src_key] - puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug - dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + ' ')) + if dest.has_key?(src_key) + if dest[src_key].nil? + puts "#{di} ==>skipping: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug + else + puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug + dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + ' ')) + end else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!) puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug # note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others) From d28c22ef9cf1afc203b527f0297430d3817322d4 Mon Sep 17 00:00:00 2001 From: dtaniwaki Date: Wed, 11 Mar 2015 12:29:45 -0700 Subject: [PATCH 2/2] Add tests for skip merge on nil destination --- test/test_deep_merge.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test_deep_merge.rb b/test/test_deep_merge.rb index 836c8af..fa03c9b 100644 --- a/test/test_deep_merge.rb +++ b/test/test_deep_merge.rb @@ -604,5 +604,20 @@ def test_deep_merge hash_src = {"item" => s2 } DeepMerge::deep_merge!(hash_src, hash_dst) assert_equal({"item" => ""}, hash_dst) + + ################################ + # Test ignoring nil destination + + # if the destination is nil, skip merging it + hash_src = {"foo" => {"bar" => 1} } + hash_dst = {"foo" => {"bar" => nil} } + DeepMerge::deep_merge!(hash_src, hash_dst) + assert_equal({"foo" => {"bar" => nil}}, hash_dst) + + # if the destination does not exists, merge it + hash_src = {"foo" => {"bar" => 1} } + hash_dst = {"foo" => {} } + DeepMerge::deep_merge!(hash_src, hash_dst) + assert_equal({"foo" => {"bar" => 1}}, hash_dst) end # test_deep_merge end