From: Samuel Tesla Date: 2003-12-06T13:02:07+09:00 Subject: Re: WeakRef and Object#hash "Robert Klemme" writes: > > Then you need to sub class Hash and override some methods if you want the > WeakHash to look like a normal hash from the outside. Indeed, with the exception of the problem I posted about the class no longer being a a weak reference, here's that subclass. Works out fairly well: ## test.rb require 'weakref' class WeakKey < WeakRef def initialize(aRef) super(aRef) # We need to change #eql? on the incoming object because the # method defined in object.c does not actualy check # #object_id it actually compares the VALUE structs passed # in. So when I override #object_id below, it doesn't completely # take care of the problem. class << aRef def eql?(ref) begin self.object_id == ref.object_id rescue WeakRef::RefError false end end end end # We need to override this so that anything that asks for our ID # will actually receive the ID of the object we are pretending to be. def object_id begin __getobj__.object_id rescue WeakRef::RefError 0 end end # Object#id is deprecated, but people use it still. Let's make sure # they get the proper ID when they do. alias_method :id, :object_id # From Robert Klemme. This simply calls the hash function from the # actual object. def hash begin __getobj__.hash rescue WeakRef::RefError 0 end end # Also from Robert Klemme. Same idea as #hash. def eql?(ref) begin __getobj__.object_id == ref.object_id rescue WeakRef::RefError false end end end a = Object.new b = WeakKey.new(a) puts(a.eql?(b).to_s) # => true puts(b.eql?(a).to_s) # => true