2006/1/24, James Edward Gray II <james / grayproductions.net>:
> On Jan 24, 2006, at 9:51 AM, Robert Klemme wrote:
>
> > Can't you just do something like this?
> >
> > require 'delegate'
> > require 'weakref'
> > WeakHash = DelegateClass(Hash)
> > class WeakHash
> >   def []=(key,val)
> >     __getobj__[WeakRef.new(key)] = WeakRef.new(val)
> >   end
> >
> >   def [](key)
> >     __getobj__[WeakRef.new(key)]
> >   end
> >
> >   def each(&b)
> >     __getobj__.each do |k,v|
> >       b[k.__getobj__, v.__getobj__] unless k.__getobj__.nil?
> >     end
> >     self
> >   end
> >
> >   def cleanup
> >     delete_if {|k,v| k.__getobj__.nil?}
> >   end
> > end
>
> I didn't see this message while the gateway was down.  Sorry about that.
>
> I can't use this code as is.  I assume you didn't set up delegation
> quite right:

What problem exactly do you have with it?

> class WeakHash < DelegateClass(Hash)
>    def initialize
>      super(Hash.new)
>    end
>
>    # ...
> end

No need to inherit to fix this. You can simply do

require 'delegate'
Wh=DelegateClass(Hash)
class Wh
  def initialize(h={})
    __setobj__ h
  end
end

> Some questions the above raises for me:
>
> 1.  What will Ruby do if a key is GCed, but not a value?

This was just rough outline code. For a production version I'd
probably change it to consider a pair as gone if either of them is
GC'ed.

> 2.  How does this code deal with a value being GCed when the key
> remains?

It will yield nil - but see 1.

> 3.  Don't we need to shut off GC in places, to keep references from
> disappearing before we can use them?

No.  Because while the yield takes place instances are hard referenced
and cannot be gc'ed.

> Thanks for the help.

Ywc

Kind regards

robert


--
Have a look: http://www.flickr.com/photos/fussel-foto/