rubychef-infrachef-attributes

Initialize Ruby hash with a constant value


Actually I want to use such constructs in chef attributes, where I initialize a structure with a constant and modify it

init_value = { "a" => { "b" => "c" } }
prepare = init_value
prepare["a"]["x"] = "y"

now init_value also contains ["a"]["x"] = "y", so when I prepare a new value

prepare = init_value
prepare["a"]["y"] = "x"

so prepare["a"] contains the keys ["b", "x", "y"].

How can I initialize prepare with a constant without quoting the constant, so that in the last step, prepare["a"] only contains the two keys ["b","y"]?


Solution

  • You could move the initial hash into a method. This way, the method always returns a "fresh" hash:

    def init_value
      {"a"=>{"b"=>"c"}}
    end
    
    prepare = init_value
    prepare["a"]["x"] = "y"
    prepare
    #=> {"a"=>{"b"=>"c", "x"=>"y"}}
    
    prepare = init_value
    prepare["a"]["y"] = "x"
    prepare
    #=> {"a"=>{"b"=>"c", "y"=>"x"}}