Hash#dig is fun, but sometimes I want to be strict … so I use dig_fetch … and dig_set to set a value without running into nil / MethodMissing errors.
# before hash.dig(:a, :b, :c) # any of these could be nil ... hash.fetch(:a).fetch(:b).fetch(:a) # repetitive and only shows last key # after hash.dig_fetch(:a, :b, :a) Hash.class_eval do def dig_fetch(*keys, last, &block) block ||= ->(*) { raise KeyError, "key not found: #{(keys << last).inspect}" } before = (keys.any? ? dig(*keys) || {} : self) before.fetch(last, &block) end def dig_set(keys, value) raise ArgumentError, "No key given" if keys.empty? keys = keys.dup last = keys.pop failed = ->(*) { raise KeyError, "key not found: #{(keys << last).inspect}" } nested = keys.inject(self) { |h, k| h.fetch(k, &failed) } nested[last] = value end end