Tim Bates wrote:
> On Mon, Aug 11, 2003 at 09:56:44PM +0900, Robert Klemme wrote:
>>Your cache implementation is exactly as it should be, but the code outside
>>should only hold on to an instance as long as it is needed, typically a
>>method invocation's duration.  The only thing the outside world should store
>>is the id, which is needed to access the instance via the cache.  A typical
>>usage pattern looks like this
> 
> Yes, except that it doesn't work:
> 
> [tim@zaphod:3 ~/ruby]$ cat weakref_test.rb 
> require 'weakref'
> 
> o = Object.new
> q = o
> o = WeakRef.new(o)
> ObjectSpace.garbage_collect
> p o
> p q
> q = nil  # o is now the only reference to the object.
> ObjectSpace.garbage_collect
> puts o

Playing around I noticed this:

require 'weakref'
o = WeakRef.new(Object.new)
puts o.__getobj__             # A
puts o.__getobj__.to_s        # B
ObjectSpace.garbage_collect
puts o

Comment out line A and B in turn. With only B, o gets GC'ed, but not 
with line A.

A wild guess: Parameters to method calls are pushed onto the stack and 
(naturally for efficiency) not cleaned away after the method call has 
ended. Thus the current call frame contains a reference to the 
"unreferenced" object, and you cannot be sure that it will disappear 
until after the call frame has been "popped" from the call stack.

Does that make any sense to someone with knowledge of the Ruby innards?

-- 
(\[ Kent Dahl ]/)_    _~_    _____[ http://www.pvv.org/~kentda/ ]_____/~
  ))\_student_/((  \__d L b__/ (pre-) Master of Science in Technology  )
( \__\_/__/ ) _)Industrial economics and technological management(
  \____/_\____/ (____engineering.discipline_=_Computer::Technology___)