インスタンスの所有者を探索するクラス
任意のインスタンスの所有者(インスタンス変数としてインスタンスを保持するインスタンス)を探索するクラスを書いてみました。
という仕組みです。クラス変数とかグローバル変数、ローカル変数で所有されているものはスルーしてます。
# インスタンスの所有者を探す。 class Owners def collect @owners = {} ObjectSpace.each_object {|object| id = object.object_id object.instance_variables.each {|n| v = object.instance_variable_get( n ) @owners[v.object_id] ||= [] @owners[v.object_id] << id } } end def owners( obj ) (@owners[obj.object_id] || []).map {|id| o = ObjectSpace._id2ref(id) "#{o.object_id} : #{o.class.to_s}" } end end
呼び出し例。
# テスト用クラス class A def initialize( obj ) @obj = obj end end class B def initialize( obj ) @obj = obj end end class C; end #簡単な所有関係を形成 c = C.new b = B.new(c) a = A.new(b) a2 = A.new(c) #探索クラス owners = Owners.new owners.collect # 現在の所有関係を記録 #所有者を探索 p owners.owners( c ) p owners.owners( b ) p owners.owners( a ) p owners.owners( a2 )
実行結果です。
["136411120 : A", "136411140 : B"] ["136411130 : A"] [] []
というか、デバッガを探せばこんな機能はありそうだな、と作ってからちょっと思った。