Hi --

On Thu, 4 Jan 2001, GOTO Kentaro wrote:

> A number of users was confused by these behavior, thus we have already
> proposed an alternative constructor [ruby-list:26622] like this:
> 
>   a = Hash.new { |hash_self, unknown_key| 
>     hash_self[unknown_key] = ""
>   }

Interesting.  (I wish I could follow ruby-list, but I don't know
Japanese and I can't get the Excite thing to work :-< )  Anyway -- I
couldn't resist playing around with this.... along with a bit of
autovivification, and even some hash/array transitioning.  So, for
anyone who wants to play, here's a little testbed:

   class Hash
     alias :oldinit :initialize
     alias :olddef :default
     alias :oldget :[]

     attr_accessor :block

     def initialize(*d, &b)
       self.block = b || false
       oldinit(*d)
     end

     def default(*arg)
       if block
	 block.call(self, *arg)
       else
	 olddef
       end
     end

     def [](k)
       self[k] = default(k) unless has_key? k
       oldget(k)
       end

     def vivify_keys(a)
       a.each do |e| self[e] = default end
       self
     end

   end

   h = Hash.new { |s,k| s[k] = "I'm the value for '#{k}'" }
   p h["new key"] #  => "I'm the value for 'new key'"

   a = "abc"
   h = Hash.new { a.succ!.dup }
   h.vivify_keys( %w< one two three > )
   p h  #  =>  {"one"=>"abd", "three"=>"abf", "two"=>"abe"}

   h[:whatever] += " is a new key"
   p h[:whatever] #  =>  "abg is a new key"


(It really is amazing how compact [yet readable] this language is!)


David

-- 
David Alan Black
home: dblack / candle.superlink.net
work: blackdav / shu.edu
Web:  http://pirate.shu.edu/~blackdav