For multi-dimension Hash, .merge will replace the values as a 2 dimension hash.
>> {"number" => {"1" => "one","2" => "two"}}.merge({"number" => {"3" => "three"}})
=> {"number"=>{"3"=>"three"}}
We needed the keep the hash values and merge complex hash together that is loaded from YAML.
Solution?
class Hash
def recursive_merge(h)
self.merge!(h) {|key, _old, _new| if _old.class == Hash then _old.recursive_merge(_new) else _new end }
end
end
>>{"number" => {"1" => "one","2" => "two"}}.recursive_merge({"number" => {"3" => "three"}})
=> {"number"=>{"1"=>"one", "2"=>"two", "3"=>"three"}}
Great! I just used it in my own app for the exact reason you mentioned (mixing non-flat configurations from two sources).
I suggest renaming the method name to
recursive_merge!
to denote that it is destructive (likemerge
).Thanks,
dubek.
I meant like
merge!
(of course).I am glad to see that recursive_merge method, it is awesome and works like I thought merge would. I went looking earlier today and lo and behold… your code showed up. I can’t believe it isn’t part of the Hash class.
Now I can finish one of my pet projects. Thank you.