クラスのアンロードがうまく出来ません

うーん、クラスがうまくアンロードできません。クラスやモジュールがGCの対象となるのは、

  • そのクラス/モジュールを指す定数が削除され(remove_const)
  • そのクラス/モジュールを利用するクラスが存在せず
  • そのクラスのインスタンスが存在しない
http://www.rubyist.net/~matz/20061227.html#p06

という三条件が揃っている時、というのは分かっているのですが、これを満たしているつもりの以下のコードではなぜかクラスのアンロードに失敗します。

GC.enable

class ABC; end

Object.class_eval{
   remove_const :ABC
}

GC.start

ObjectSpace.each_object(Class){|obj|
   p obj if obj.name == 'ABC' # => ABC
}

なにが悪いのでしょうか。remove_constで :ABC は削除してるし、ABCを利用しているクラスやモジュールはなく、ABCのインスタンスもない。と思うのですが、実際には私が気付いていないだけでなにかがABCを参照しているのでしょうか。

でも、これと同じのをirbでやると、確かにアンロードされるんだけどなぁ。

追記

やっぱり基本的にはアンロードされる条件を満たしているような気がします。

GC.enable

class C1; end
class C2; end
class C3; end
class C4; end
class C5; end

$list = []

ObjectSpace.each_object(Class){|obj|
   $list << obj.name
}

Object.class_eval{
   remove_const :C1
   remove_const :C2
   remove_const :C3
   remove_const :C4
   remove_const :C5
}

GC.start

ObjectSpace.each_object(Class){|obj|
   $list.delete_if{ |c| c == obj.name }
}

p $list
p $list.size

これを"ruby 1.8.6 (2007-06-07 patchlevel 36) [i486-linux]"で実行してみると結果は次のようになります。

["C4", "C3", "C2", "C1"]
4

また"ruby 1.8.6 (2008-03-03 patchlevel 114) [i686-linux]"で実行してみると。

["C3", "C2", "C1"]
3

さらに"ruby 1.9.0 (2008-03-14 revision 0) [i686-linux]"で実行してみると。

[]
0

というわけで、結果はただの気紛れなんじゃないのか、という気がします。とにかく一応、GCされないこともないことが分かったので、これで良しとします。