On 3/11/06, Javier Valencia <jvalencia / log01.org> wrote:
> tigre@enigma tigre $ irb
> irb(main):001:0> events = {}
> => {}
> irb(main):002:0> events.default = []
> => []
> irb(main):003:0> events["trying"] << "hello"
> => ["hello"]
> irb(main):004:0> events
> => {}
> irb(main):005:0> events.inspect
> => "{}"
> irb(main):006:0> events["trying"]
> => ["hello"]
> irb(main):007:0> quit
> tigre@enigma tigre $
>
>
> why is happening this behaviour?

Take a look at this for some clues:

  $ irb
  irb(main):001:0> events = {}
  => {}
  irb(main):002:0> events.default = []
  => []
  irb(main):003:0> events["trying"] << "hello"
  => ["hello"]
  irb(main):004:0> events.default
  => ["hello"]
  irb(main):005:0> events["test"]
  => ["hello"]

In short, what's happening is that when you call events["trying"] at
statement 3, it returns the default value, which is an array. You then
insert "hello" into that array and *change the default value*. Since
you never assigned to events["trying"], it still doesn't exist. You
were only getting the expected value back on re-access because of the
changed default value.

Try this instead:

  $ irb
  irb(main):001:0> events = Hash.new{ |h,k| h[k] = [] }
  => {}
  irb(main):002:0> events.default
  => []
  irb(main):003:0> events["trying"] << "hello"
  => ["hello"]
  irb(main):004:0> events.default
  => []
  irb(main):005:0> events["trying"]
  => ["hello"]
  irb(main):006:0> events["test"]
  => []
  irb(main):007:0> events
  => {nil=>[], "test"=>[], "trying"=>["hello"]}

This produces the desired behavior, but you have to be careful, since
accessing non-existent keys will pollute the keys of your hash.

--
Jacob Fugal