From: Martin DeMello Date: 2005-11-10T01:57:13+09:00 Subject: Re: Nested hash constructor confusion Ben Armstrong wrote: > Can anyone explain the following? Our "intuitive" solution (h1) to > creating a constructor for a hash nested within a hash did not work. It > was only after attempting a workaround (h3) and finding that it > performed very poorly that we Googled (h2) a correct solution. But it > is not obvious to us why this more complex constructor is required. Hash.new, when passed a block, stores the block as a sort of "key_missing" callback, passing it the hash itself and the key. The callback doesn't modify the hash, though, it just returns a virtual value. However, because the block does have access to the hash, it can call a method on that hash that updates it, hence the second constructor you tried. Compare: irb(main):001:0> h = Hash.new {|h, k| 2*k} => {} irb(main):002:0> h[1] => 2 irb(main):003:0> h[2] => 4 irb(main):004:0> h => {} irb(main):005:0> h1 = Hash.new {|h, k| h[k] = 2*k} => {} irb(main):006:0> h1[1] => 2 irb(main):007:0> h1[2] => 4 irb(main):008:0> h1 => {1=>2, 2=>4} And even something more complicated like: irb(main):009:0> h2 = Hash.new {|h, k| h[k] = 2*k; "missing, filling it in"} => {} irb(main):010:0> h2[1] => "missing, filling it in" irb(main):011:0> h2[1] => 2 martin martin