From b00f0ba44a2cc9bbfc7da439568d5e43f4b4678b Mon Sep 17 00:00:00 2001 From: Don Buchanan Date: Sat, 12 Jun 2010 19:23:50 +1000 Subject: [PATCH] added block to ordered hash merge [#3590 state:resolved] didn't add any code for deep merging, it seem to work fine --- activesupport/lib/active_support/ordered_hash.rb | 15 +++++-- activesupport/test/ordered_hash_test.rb | 45 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index e1a2866..958386b 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -129,13 +129,20 @@ module ActiveSupport [k, v] end - def merge!(other_hash) - other_hash.each {|k,v| self[k] = v } + def merge!(other_hash) + other_hash.each do |k, v| + # only run the block when we have a value in both hashes + if block_given? and (!self[k].nil? and !v.nil?) + self[k] = yield(k, self[k], v) + else + self[k] = v + end + end self end - def merge(other_hash) - dup.merge!(other_hash) + def merge(other_hash, &block) + dup.merge!(other_hash, &block) end # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not. diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb index d070206..98c8006 100644 --- a/activesupport/test/ordered_hash_test.rb +++ b/activesupport/test/ordered_hash_test.rb @@ -146,6 +146,51 @@ class OrderedHashTest < Test::Unit::TestCase assert_equal @ordered_hash, merged assert_equal @ordered_hash.keys, merged.keys end + + def test_block_merge + other_hash = ActiveSupport::OrderedHash.new + other_hash['blue'] = '001111' + other_hash['violet'] = '000111' + + merged = @ordered_hash.merge(other_hash){|key, old_value, new_value| old_value + new_value} + # should use the block to get new values + assert_equal '000099001111', merged['blue'] + # should add new values unchanged + assert_equal '000111', merged['violet'] + assert_equal @keys + ['violet'], merged.keys + end + + def test_deep_merge + @ordered_hash['deep'] = ActiveSupport::OrderedHash.new + @ordered_hash['deep']['number'] = 1 + + other_hash = ActiveSupport::OrderedHash.new + other_hash['deep'] = ActiveSupport::OrderedHash.new + other_hash['deep']['number'] = 5 + other_hash['deep']['place'] = 'here' + + merged = @ordered_hash.deep_merge(other_hash) + + #should merge the nested hash + assert 5, merged['deep']['number'] + assert 'here', merged['deep']['place'] + end + + def test_deep_block_merge + @ordered_hash['deep'] = ActiveSupport::OrderedHash.new + @ordered_hash['deep']['number'] = 1 + + other_hash = ActiveSupport::OrderedHash.new + other_hash['deep'] = ActiveSupport::OrderedHash.new + other_hash['deep']['number'] = 5 + other_hash['deep']['place'] = 'here' + + merged = @ordered_hash.deep_merge(other_hash){|key, old_value, new_value| old_value + new_value} + + #should merge the nested hash + assert 6, merged['deep']['number'] + assert 'here', merged['deep']['place'] + end def test_shift pair = @ordered_hash.shift -- 1.7.0.1