おおしまです。

Ryo HAYASAKA wrote:
[snip]
>  試しに weakref.rb の Usage のようにして実行してみたんです
> が、
> 
> ruby 1.3.1 (1999-03-15) [i686-linux]
> 
> require "weakref"
> 
> foo = Object.new
> foo = WeakRef.new(foo)
> ObjectSpace.garbage_collect
> foo.hash    # => Raises WeakRef::RefError (because original GC'ed)
> 
> コメントにあるような例外があがりません。
>  weakref.rb の最後にあるように foo.to_s なら例外があがります。
> 
>  Usage が間違ってるのか、Ruby が悪いのか、僕の理解不足か?

Delegator.rbによると、hashはdelegateの対象にはなってないようですね。
ということで、正常な動作だと思います。Delegator.rbにある
サンプルが間違ってるのかな?

あと、大きな問題ではないと思うのですが、

foo = Object.new
WeakRef.new(foo)
WeakRef.new(foo)

とすると、メモリリークが起きてしまうような気がします。
(先に作られたリファレンスのidのエントリが残ってしまう。)
すでに存在する場合にはそれを返すようなメソッドが
あった方がよいのでは? たとえば、

def WeakRef.getRef(obj)
  rid = ID_MAP[obj.__id__]
  if rid
    return ObjectSpace._id2ref(rid)
  elsif
    return WeakRef.new(obj)
  end
end

のような。このままだとthread safeでなかったり、途中でGCされたりすると
こまってしまいますが、、、

- Oshima