From: Kazuhiro HIWADA Date: 1999-06-23T02:48:46+09:00 Subject: [ruby-dev:7174] WeakRef? ひわだです。 WeakRefというか、GCの挙動について教えてください。Flyweightパターンとか に使えるかと思い、GCでdataが回収されるようなweakなHashを書きました。 WeakRefは、拡張してリファレンス先が解放されるときにコールバックしてく れるようにしています。#長くなるので添付しませんが以下においてます。 http://easter.kuee.kyoto-u.ac.jp/~hiwada/ruby/memo/src/wrefwfr.rb ↓ここから require 'wrefwfr.rb' class WeakHash < Hash alias assign []= def alive?(k) key?(k) && self[k].weakref_alive? end def []=(k,v) assign(k, wr = WeakRefWFR.new(v)) # v = nil # ←注目!!! wr.weakref_set_fin_event{ self.assign(k, nil) } end end b = Hash.new b[1] = (wr = WeakRefWFR.new("1")) wr.weakref_set_fin_event{ b[1] = nil } p ["b", b]; ObjectSpace.garbage_collect; p ["b", b] a = WeakHash.new a[1] = "1" p ["a", a]; ObjectSpace.garbage_collect; p ["a", a] ↑ここまで 上のスクリプトを実行すると、 % ruby -v hoge.rb ruby 1.3.4 (1999-05-31) [i386-linux] ["b", {1=>"1"}] ["b", {}] ["a", {1=>"1"}] ["a", {1=>"1"}] "b" と同じように、"a" の方もGCで回収してほしいのですが失敗してます。さ らに、「注目!!!」行のコメントを外し v = nil すると % ruby -v hoge.rb ruby 1.3.4 (1999-05-31) [i386-linux] ["b", {1=>"1"}] ["b", {}] ["a", {1=>"1"}] ["a", {}] となって、こんどは所望の動作をします。1.3.4 (1999-06-11) でも同様。 weakref_set_fi...に渡している{ self.assign(k, nil) }というブロックから v の値に何らかのリファレンスがあるのだろうかとか推測してますが、「v = nil」ってのは、必要なものでしょうか?。それとも実はこんなスクリプトは 書いてはいけなくて、偶然動いてしまったのでしょうか ^^;;;。 #似た話を見掛けた気がしたんですが、見つからず… (__; -- 檜田和浩