Search code examples
ruby-on-railsrubyhashparameters

Is there an equivalent method for Ruby's `.dig` but where it assigens the values


Let's say we're using .dig in Ruby like this:

some_hash = {}
some_hash.dig('a', 'b', 'c')
# => nil

which returns nil

Is there a method where I can assign a value to the key c if any of the other ones are present? For example if I wanted to set c I would have to write:

  some_hash['a'] = {} unless some_hash['a'].present?
  some_hash['a']['b'] = {} unless some_hash['a']['b'].present?
  some_hash['a']['b']['c'] = 'some value'

Is there a better way of writing the above?


Solution

  • That can be easily achieved when you initialize the hash with a default like this:

    hash = Hash.new { |hash, key| hash[key] = Hash.new(&hash.default_proc) }
    hash[:a][:b][:c] = 'some value'
    hash
    #=> {:a=>{:b=>{:c=>"some value"}}}
    

    Setting nested values in that hash with nested defaults can partly be done with dig (apart from the last key):

    hash.dig(:a, :b)[:c] = 'some value'
    hash
    #=> {:a=>{:b=>{:c=>"some value"}}}