On Tuesday 05 January 2010 09:39:53 pm Ruby Newbee wrote: > irb(main):039:0> hash = Hash.new [] I assume here that [] is the default value, right? > => {} > irb(main):040:0> hash['abc'] << 3 > => [3] > irb(main):041:0> hash.keys > => [] > irb(main):042:0> hash['def'] > => [3] > > > Since I have created a key/value pair with hash['abc'] << 3, why > hash.keys show nothing? Because you haven't set anything in the hash. That is, hash['abc'] = 3 is equivalent to: hash.[]=('abc', 3) On the other hand, what you've done is: hash['abc'] << 3 That's equivalent to: hash.[]('abc') << 3 I don't know if that helps, but that's the difference. Let me put it this way -- suppose you hadn't changed the default value: irb(main):001:0> hash = {} => {} irb(main):002:0> hash['abc'] => nil irb(main):003:0> hash.keys => [] Do you understand why that works the way it does? But there's nothing special about nil here, it's just the, erm, _default_ default value -- it's what Hash uses as a default value if you don't specify one. > And, why hash['abc'] << 3 changed the hash's default value (which > should be an empty array)? Because you set the default value to [], which creates an empty array object, once. The hash is just assigning it each time. Think of it this way: irb(main):004:0> default = [] => [] irb(main):005:0> a = default => [] irb(main):006:0> b = default => [] irb(main):007:0> a << 3 => [3] irb(main):008:0> b => [3] What you really want is the block notation of creating a hash, which lets you actually specify some code that's run to create a default value, as Bill Kelly says. The reason his code works is that when you try to access a value that doesn't exist, it actually runs some code which sets that value: h = Hash.new {|h,k| h[k] = []} It wouldn't work at all if you just did this: h = Hash.new {|h,k| []} That would at least give you a new array each time, but since it wouldn't set it, you'd see weird things: irb(main):010:0> h['abc'] << 3 => [3] irb(main):011:0> h['abc'] => [] irb(main):012:0> h.keys => []