1

I want to use a hash as a bigger hash's default value. But I don't know how to set the inner hash's value through the outer hash.

h = Hash.new do 
  {:counter => 0}
end
h[:a][:counter] += 1
=> 1 
h[:a][:counter] += 1
=> 1
h[:a][:counter] += 1
=> 1 
h
=> {}

Uh, what's the right way?

Lai Yu-Hsuan
  • 27,509
  • 28
  • 97
  • 164

2 Answers2

4

If you initialize with a default value of a hash:

h = Hash.new({:counter => 5})

Then you can follow the calling pattern in your example:

h[:a][:counter] += 1
 => 6 
h[:a][:counter] += 1
 => 7 
h[:a][:counter] += 1
 => 8

Alternatively you may want to intialize with a block so a new instance of the :counter hash is created every time you use a new key:

# Shared nested hash
h = Hash.new({:counter => 5})
h[:a][:counter] += 1
 => 6 
h[:boo][:counter] += 1
 => 7 
h[:a][:counter] += 1
 => 8 

# New hash for each default
n_h = Hash.new { |hash, key| hash[key] = {:counter => 5} }
n_h[:a][:counter] += 1
 => 6 
n_h[:boo][:counter] += 1
 => 6 
n_h[:a][:counter] += 1
 => 7 
Matt Glover
  • 1,347
  • 7
  • 13
0
def_hash={:key=>"value"}
another_hash=Hash.new(def_hash)
another_hash[:foo] # => {:key=>"value"}
gprasant
  • 15,589
  • 9
  • 43
  • 57