ruby 28 lines · 8 steps

Recursively merging nested config hashes in Ruby

A module that deep-merges two hashes, combining nested hashes and arrays instead of clobbering them.

Explained by highlit
1module ConfigMerge
2 module_function
3 
4 def deep_merge(base, override)
5 base.merge(override) do |_key, base_val, override_val|
6 if base_val.is_a?(Hash) && override_val.is_a?(Hash)
7 deep_merge(base_val, override_val)
8 elsif base_val.is_a?(Array) && override_val.is_a?(Array)
9 (base_val + override_val).uniq
10 else
11 override_val
12 end
13 end
14 end
15 
16 def deep_merge!(base, override)
17 override.each do |key, override_val|
18 base_val = base[key]
19 base[key] =
20 if base_val.is_a?(Hash) && override_val.is_a?(Hash)
21 deep_merge!(base_val, override_val)
22 else
23 override_val
24 end
25 end
26 base
27 end
28end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Passing a block to `merge` lets you decide per-key how conflicting values combine instead of blindly overwriting.
  2. 2Recursing into nested hashes lets a merge preserve deep structure rather than replacing whole subtrees.
  3. 3Offering both a pure and a bang variant gives callers the choice between safety and in-place efficiency.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Recursively merging nested config hashes in Ruby — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code