0

I'm getting some rather unexpected behavior from hashes in ruby

here's a simplified demonstration of the problem

estdata = ["a","b","c"]
outputHash = Hash.new({:IDs => [], :count => 0})

estdata.each do |x|
  outputHash[x][:IDs] << x
  outputHash[x][:count] +=1
end

p outputHash # => {}
p outputHash["a"] # => {:count=>3, :IDs=>["a", "b", "c"]}

So firstly, why does the first p output an empty hash when clearly outputHash isn't empty?

And secondly and much more to my frustration and confusion, why does is seem that every key in the has points to a single value (the hash containing the :count and :IDs keys) and how would I get around this?

Mat
  • 202,337
  • 40
  • 393
  • 406
Nat
  • 2,689
  • 2
  • 29
  • 35

1 Answers1

5

With Hash.new and a parameter everything will point to the same object.

>> h = Hash.new('hello') #=> {}
>> h[:a] #=> "hello"
>> h[:a].object_id #=> 2152871580
>> h[:b].object_id #=> 2152871580
>> h[:c].object_id #=> 2152871580

What you want is the block form:

>> h = Hash.new { |h,k| h[k] = {} } #=> {}
>> h[:a].object_id #=> 2152698160
>> h[:b].object_id #=> 2152627480
Michael Kohl
  • 66,324
  • 14
  • 138
  • 158
  • thank you, yes using `outputHash = Hash.new{|h,k| h[k]={:IDs => [], :count => 0}}` does what I want :) – Nat Jun 22 '11 at 10:44