Safely assign value to nested hash using Hash#dig or Lonely operator(&.) Safely assign value to nested hash using Hash#dig or Lonely operator(&.) ruby ruby

Safely assign value to nested hash using Hash#dig or Lonely operator(&.)


It's not without its caveats (and doesn't work if you're receiving the hash from elsewhere), but a common solution is this:

hash = Hash.new {|h,k| h[k] = h.class.new(&h.default_proc) }hash[:data][:user][:value] = "Bob"p hash# => { :data => { :user => { :value => "Bob" } } }


And building on @rellampec's answer, ones that does not throw errors:

def dig_set(obj, keys, value)  key = keys.first  if keys.length == 1    obj[key] = value  else    obj[key] = {} unless obj[key]    dig_set(obj[key], keys.slice(1..-1), value)  endendobj = {d: 'hey'}dig_set(obj, [:a, :b, :c], 'val')obj #=> {d: 'hey', a: {b: {c: 'val'}}} 


interesting one:

def dig_set(obj, keys, value)  if keys.length == 1    obj[keys.first] = value  else    dig_set(obj[keys.first], keys.slice(1..-1), value)  endend

will raise an exception anyways if there's no [] or []= methods.