One way to merge nested configs cleanly:
- flatten key paths
- merge
This approach overcomes the issue of performing a deep merge when an overlay has the ability to specify a value or a hash. This does not deal with merging array values.
Here is the issue:
c1 = {"a" => 1}
c2 = {"a" => 2}
c3 = {"a" => {"b" => 1}}
c4 = {"a" => {"b" => 2}}
deep_merge(c1, c2)
# => {"a" => 2}
deep_merge(c3, c4)
# => {"a" => {"b" => 2}}
deep_merge(c1, c4)
# => {"a" => 1} # preserve value (?)
# => {"a" => {"b" => 2}} # preserve hash (?)
Here is the a solution:
flat_merge(c1, c2)
# => {"a" => 2}
flat_merge(c3, c4)
# => {"a" => {"b" => 2}}
flat_merge(c1, c4)
# => {"a" => 1, "a.b" => 2}
Note that in a flat merge a flat key is equivalent to the key path in the nested structure:
c1 = {"a.b" => 1}
c2 = {"a" => {"b" => 2}}
flat_merge(c1, c2)
# => {"a.b" => 2}