From: ko1@... Date: 2015-05-23T20:15:16+00:00 Subject: [ruby-dev:48993] [Ruby trunk - Bug #11173] inter class/module alias causes "no superclass method" Issue #11173 has been updated by Koichi Sasada. 似たような話なんですが、 ```ruby module M0 private def foo p M0 end end class C0 def foo p C0 end end class C1 < C0 include M0 public :foo end module M0 remove_method :foo end C1.new.foo ``` これだと、C1#foo は METHOD_TYPE_ZSUPER として定義されており、M0#foo が無くなったので、C0#foo を探し出し、無事に C0#foo が実行されます。 しかし、 ```ruby module M0 private def foo p M0 end end class C0 def foo p C0 end end module M1 include M0 public :foo end module M0 remove_method :foo end class C1 < C0 include M1 end C1.new.foo #=> test.rb:27:in `
': undefined method `foo' for # (NoMethodError) ``` と、(多分)ちゃんと動きません。M1#foo が ZSUPER なのだけれど、M1 の T_ICLASS より上を探そうとして、T_ICLASS(M0) を探して、見つからない → T_ICLASS(M0) の super は無いので、探索終了→メソッド見つからず、となります。 ---------------------------------------- Bug #11173: inter class/module alias causes "no superclass method" https://bugs.ruby-lang.org/issues/11173#change-52610 * Author: Koichi Sasada * Status: Open * Priority: Normal * Assignee: * ruby -v: * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- ```ruby class C0 def foo p :C0 end end module M0 def foo p :M0 super end end module M1 include M0 alias orig_foo foo end class C1 < C0 include M1 end p C1.ancestors C1.new.orig_foo ``` 結果: ``` ruby 2.3.0dev (2015-05-21 trunk 50502) [i386-mswin32_110] [C1, M1, M0, C0, Object, Kernel, BasicObject] :M0 test.rb:12:in `foo': super: no superclass method `foo' for # (NoMethodError) from test.rb:26:in `
' ``` M0#foo の super である C0#foo が呼ばれてもいいと思うのですが、 この挙動はそういうもんでしたっけ。 挙動的には、M1 の alias で作られる method_entry が M0 の T_ICLASS (TI1) を指すけど、C1 からの継承関係で作られる M0 を指す T_ICLASS (TI2)と、TI1 が関係ないから、起こっているんだと思います。 なんか、class/module をまたいだ alias の挙動(と、その super での挙動)が色々怪しい感じです。 -- https://bugs.ruby-lang.org/