On Wed, Sep 03, 2003 at 10:54:09AM +0900, Alan Chen wrote:
> Hmm, I meant h[k] not h[h] as I originally posted below...
> 
> md = Hash.new { |h,k| h[k] = 0; 3 }
> # access undefined key 1
> p md[1]   # => 3  # returns the block result
> p md[1]   # => 0  # now we discover the actual default value
> 
> It's clear to me exactly what is happening, but I guess my thought was 
> that this behavior is a bug. If the code that runs the autovivication 
> block can recognize that the value for the undefined key was set, then 
> perhaps the block return value should be ignored. I guess it would 
> require an additional st_lookup after the initial lookup fails.

It's not a bug.  The block you pass to Hash.new is not expected to
do anything but return the value that the hash should return for the
given key when no value is yet stored for that key.  That's all.
There's no requirement or expectation that the block modify the hash,
even though it has the ability to do so.  

If the block does modify the hash at all, it's not unreasonable to assume
that the modification will consist of storing the same value that the block
is returning at the key that was requested.  If it does something else,
then it's the programmer, not Ruby, who's violating the principle of
least surprise. :)

In other words, you have it backwards.  The return value of the block is
the important thing from the standpoint of the Hash specification; anything
else is just a side effect.  Which the autovivification solution presented
earlier in this thread was exploiting.

-Mark