> [growinghash.rb]require 'delegate'
>
> class GrowingHash < DelegateClass(Hash)
>   def initialize(*a,&b)
>     super(Hash === a[0] ? a[0] : Hash.new(*a,&b))
>   end
>
>   def store(k,v)
>     raise ArgumentError, "Key already set: #{k.inspect}" if key? k
>     super
>   end
>
>   alias []= store
>
>   def set_if_unset(k,v=nil)
>     store(k, block_given? ? yield : v) unless key? k
>   end
> end

Is this intended to be thread-safe?  Am I missing something with the
lack of locking in the store method...?

What stops two threads doing a store of the same key sometimes letting
both stores go through?

For example, the timeline:
Thread1     Thread2
-------     -------
raise ArgumentError, "Key already set: #{k.inspect}" if key? k
            raise ArgumentError, "Key already set: #{k.inspect}" if
key? k
super
            super
-------------------