Consider this code:
h = Hash.new(0) # New hash pairs will by default have 0 as values
h[1] += 1 #=> {1=>1}
h[2] += 2 #=> {2=>2}
The operator +=
when applied to those hashes work as expected.
[1] pry(main)> foo = Hash.new( [] )
=> {}
[2] pry(main)> foo[1]+=[1]
=> [1]
[3] pry(main)> foo[2]+=[2]
=> [2]
[4] pry(main)> foo
=> {1=>[1], 2=>[2]}
[5] pry(main)> bar = Hash.new { [] }
=> {}
[6] pry(main)> bar[1]+=[1]
=> [1]
[7] pry(main)> bar[2]+=[2]
=> [2]
[8] pry(main)> bar
=> {1=>[1], 2=>[2]}
This may be because foo[bar]+=baz
is syntactic sugar for foo[bar]=foo[bar]+baz
when foo[bar]
on the right hand of =
is evaluated it returns the default value object and the +
operator will not change it. The left hand is syntactic sugar for the []=
method which won't change the default value.
Note that this doesn't apply to foo[bar]<<=baz
as it'll be equivalent to foo[bar]=foo[bar]<
<<
will change the default value.
Also, I found no difference between Hash.new{[]}
and Hash.new{|hash, key| hash[key]=[];}
. At least on ruby 2.1.2 .