Skip to content

Instantly share code, notes, and snippets.

@emrekutlu
Created January 11, 2010 09:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emrekutlu/274118 to your computer and use it in GitHub Desktop.
Save emrekutlu/274118 to your computer and use it in GitHub Desktop.
module ActiveSupport
class OrderedHash
def merge!(other_hash)
other_hash.each do |k, v|
self[k] = block_given? ? yield(k, self[k], v) : v
end
self
end
def merge(other_hash, &block)
dup.merge!(other_hash, &block)
end
end
end
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module Hash #:nodoc:
# Allows for deep merging
module DeepMerge
# Returns a new hash with +self+ and +other_hash+ merged recursively.
def deep_merge(other_hash)
self.merge(other_hash) do |key, oldval, newval|
oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
newval = newval.to_hash if newval.respond_to?(:to_hash)
(oldval.class.to_s == 'Hash' || oldval.class.to_s == 'ActiveSupport::OrderedHash') && (newval.class.to_s == 'Hash' || newval.class.to_s == 'ActiveSupport::OrderedHash') ? oldval.deep_merge(newval) : newval
end
end
end
end
end
end
def test_deep_merge
@ordered_hash['deep'] = ActiveSupport::OrderedHash.new
@ordered_hash['deep']['number'] = 1
@ordered_hash['deep']['place'] = 'here'
other_hash = ActiveSupport::OrderedHash.new
other_hash['deep'] = ActiveSupport::OrderedHash.new
other_hash['deep']['number'] = 5
merged = @ordered_hash.deep_merge(other_hash)
#should merge the nested hash
assert 5, merged['deep']['number']
assert 'here', merged['deep']['place']
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment