Backport #567
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
=begin 遠藤です。 http://d.hatena.ne.jp/sumim/20080913/p1 の最後で指摘されていることですが、1.8 の継承関係がおかしいと 思います。 Kernel は Module のインスタンスなので、Kernel の特異クラスの superclass は Module になることを期待しますが、今の 1.8 は Module の特異クラスが superclass になっています。 1.8 がこうなった経緯は [ruby-dev:23690] や [ruby-list:40520] の ようです。 この話のもともとの問題は [ruby-list:40525] にありますが、特異 クラスは Class のインスタンスであって、Class のサブクラスじゃ ないのは不思議なことではないです。例えば、何かのオブジェクトが Object のサブクラスじゃなくても不思議じゃないです。 また、このプログラムで定義されたメソッドは、呼び出しても bind argument must be an instance of Class (TypeError) になるだけです。 モジュール Foo を self として Class#allocate を実行しようと しているので、正常な例外です。 つまりもともとの問題のプログラムは、通るようにする理由がない と思います。 ただ、この話は define_method の時に型チェックするようになった 1.9 だけで起きる現象だと思うのですが、なぜかパッチは 1.8 だけに 入っています。2005 年当時は状況が違ったのかもしれませんが。 以上より、1.8 から問題のパッチをはずした方がいいと思います。 どうでしょうか。 Index: object.c =================================================================== --- object.c (revision 19361) +++ object.c (working copy) @@ -1363,11 +1363,6 @@ rb_raise(rb_eTypeError, "compared with non class/module"); } - if (FL_TEST(mod, FL_SINGLETON)) { - if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl) - return Qtrue; - mod = RBASIC(mod)->klass; - } while (mod) { if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl) return Qtrue; @@ -1674,9 +1669,6 @@ if (!super) { rb_raise(rb_eTypeError, "uninitialized class"); } - if (FL_TEST(klass, FL_SINGLETON)) { - super = RBASIC(klass)->klass; - } while (TYPE(super) == T_ICLASS) { super = RCLASS(super)->super; } -- Yusuke ENDOH <mame@tsg.ne.jp> =end