From: "Mark J. Reed" Date: 2003-09-04T04:03:32+09:00 Subject: Re: show me the ruby way On Wed, Sep 03, 2003 at 11:45:50AM -0700, Alan Chen wrote: > "Mark J. Reed" wrote in message news:<20030903145103.GC17861@mulan.thereeds.org>... > > 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 > > 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 > > From my standpoint this code should either return > 3 3, or 0 0, but not 3 0. If the return value of the block > is to be the intended semantic, shouldn't the second line return 3 too? No. The block is ony used for return values WHEN THE KEY DOESN'T EXIST IN THE HASH. That is the whole point of the block - you only supply one when you want the hash to return something other than nil for missing keys, and specifically when you want dynamic on-the-fly control of exactly what is returned based on the key value and/or the current contents of the hash. The first time md[1] is queried, the key doesn't exist in the hash, so the block is executed and its return value (3) returned. But because the block also actually stores a value in md[1], on the next attempt to access md[1] the key DOES exist, and therefore the block is not executed at all. The hash just returns the stored value, which is 0. Having the block modify the hash is a side effect. Having the block modify the hash AND return a different value than the one it stores is just plain weird, and if you do it you deserve whatever you get. :) -Mark