Issue #11189 has been updated by Koichi Sasada.


今、こんなコードだと、

* C1 (m_tbl 空)
* T_ICLASS(m_tbl 空) -> P
* T_ICLASS(C1 の m_tbl) -> C1
* C0
* Object...

という継承関係(下が親)が作られるけど、alias のために C1 に m_tbl 作らないといかんね、って話な気がします。が、なんか以前この話をしていたことがあったような。結局 C1 にはテーブル作れないんでしたっけ。

メソッド定義については、

* alias の時は、C1::m_tbl へ
* メソッド定義の時は T_ICLASS(C1 の m_tbl)へ

と分けなきゃいけないのも、なんかかっこ悪いですね。


----------------------------------------
Bug #11189: alias prepended module
https://bugs.ruby-lang.org/issues/11189#change-52657

* Author: Koichi Sasada
* Status: Open
* Priority: Normal
* Assignee: Yukihiro Matsumoto
* ruby -v: 
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
```ruby
module P
  def m1
    p :P_m1
    super
  end

  def m2
    p :P_m2
    super
  end
end

class C0
  def m1
    p :C0_m1
  end
end

class C1 < C0
  def m1
    p :C1_m1
    super
  end
  prepend P
  alias m2 m1
end

C1.new.m2
```

このプログラムは、

```
:P_m2
:P_m1
:C0_m1
```

という結果になります。super で辿っているはずなのに、同じモジュールのメソッドが 2 回呼ばれます。super で辿っていったら、必ず継承元へ行く、2度同じクラスは来ない、という常識があると思っていたので、Ruby 的にはかなり驚きました。

この挙動は、設定時に:

* alias で C1 のメソッドテーブルに、C1#m2 を P#m1 へ飛ばすように設定する

次に、呼び出された時に:

* m2 が呼ばれる
* P#m2 を実行する
* P#m2 の super を呼ぶ
* C1#m2 を見ると、P#m1 へ飛ぶように alias が設定されている
* P#m1 を実行する、super する
* (なんでか C1#m1 をスキップする なんで?)
* C0#m1 が呼ばれる

となっておりました。P#m2 -> P#m1 という流れがとても気持ち悪いですが、これは意図された挙動でしょうか。

C1#foo が呼ばれないのも気持ち悪いですが。

ちなみに、2.1 では C1#m1 が呼ばれていました。

```
* ruby 2.1.5p312 (2015-03-10 revision 49912) [i386-mswin32_110]
:P_m2
:P_m1
:C1_m1
:C0_m1
```

たしか、alias + prepend の議論が以前あったと思うのですが。
あ、[Bug #7842] だ。

ちなみに、私の予想は

```
:P_m1
:C1_m1
:C0_m1
```

かなぁ。




-- 
https://bugs.ruby-lang.org/