Hash.new()の引数に何かを与えると、デフォルト値が与えられて初期化しなくてすむ。と言う認識なんだけど、
irb(main):001:0> a = Hash.new({})
=> {}
irb(main):002:0> a['a']['b'] = 1
=> 1
irb(main):003:0> a
=> {}
irb(main):004:0> a['a']
=> {"b"=>1}
え?
irb(main):005:0> a = {}
=> {}
irb(main):006:0> a['a'] = {}
=> {}
irb(main):007:0> a['a']['b'] = 1
=> 1
irb(main):008:0> a
=> {"a"=>{"b"=>1}}
これが期待されるよね普通。何が分かってないんだろう?
(追記)
あー。リファレンスちゃんと読んだら半分分かった。
値が設定されていないハッシュの参照はこのデフォルトオブジェクトを 返しているだけです。
に該当するんだね。
それで、ここに書いたような仕様を実装したい場合には、どうやらブロック指定をしてあげると良いようだ。
irb(main):001:0> a = Hash.new{|h, k| h[k] = {}}
=> {}
irb(main):002:0> a['a']['b'] = 1
=> 1
irb(main):003:0> a
=> {"a"=>{"b"=>1}}
でもリファレンスには
値が設定されていないハッシュ要素を参照するとその都度ブロックを 実行し、その結果を返します。
とある。この文ってこの場合3行目がa['a']の"参照"で、結局{}が帰って来る様に解釈できるんだけど。
1) ruby v1.7の仕様とあるので仕様が変わった
2) 実は2行めがa['a']の最初の参照扱い
3) ブロックが実行された時点でhには{"b"=>1}が入ってる
3かな。
うーん多重ハッシュってめちゃくちゃ使うと思うんだけど、この面倒さはアリなのかな。
まあよく分かんない事を考え込んでも時間の無駄なので、RTFMQだね。さくさく読もう。