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