I just noticed that ruby Hash#merge has a form that takes a block, where you can customize how the merging happens.
This makes it easy to write your own custom-fitted #deep_merge. (I actually noticed it existed when looking at the source for Rails3 ActiveSupport #deep_merge.)
It’s hard to write a ‘general purpose’ deep merge of hashes, exactly what you want in a deep-merge sort of depends on your situtation and the nature of your data. For instance, the ActiveSupport one was not what I wanted, as it didn’t handle combining arrays.
Here’s one that does what I needed. Yeah, could have monkey-patched it onto Hash instead, leading to more OO-looking code when calling, but I get a bad feeling from monkey-patching onto standard library objects, so generally don’t.
# Merges new_hash into source_hash, without modifying arguments, but # will merge nested arrays and hashes too. Also will NOT merge nil or blank # from new_hash into old_hash def deep_safe_merge(source_hash, new_hash) source_hash.merge(new_hash) do |key, old, new| if new.respond_to?(:blank) && new.blank? old elsif (old.kind_of?(Hash) and new.kind_of?(Hash)) deep_merge(old, new) elsif (old.kind_of?(Array) and new.kind_of?(Array)) old.concat(new).uniq else new end end end