From: Yukihiro Matsumoto Date: 2011-06-03T18:43:20+09:00 Subject: [ruby-dev:43620] Module#mix まつもと ゆきひろです Module#mixが導入されました。まあ、そのことそのものには賛成な のですが、さらに仕様を詰めないといけないような気がしている部 分があります。仕様について言及した私のブログでもすでに述べら れています。 (引用) mixされるモジュールが別のモジュールをincludeしていた場合に はどうなるか。 おそらくは例外になる。mixとincludeは混ぜるべ きではない。 現在の実装で試してみましょう。 module Foo def m end end module Bar include Foo end class Baz mix Bar end p Baz.new.m mがNoMethodErrorになります。つまり、現状BarはFooをインクルー ドしているにも関わらず、無視されているわけですね。これはエラー になるべきでしょう。 (引用) mixで別名を付けて問題解決、と読めるような言い方をしているが、 実際にはモジュール内部で名前を書き換える前のメソッドを読ん でいる可能性がある。 それをどうするか。なにもしない(重複す る方が悪い)とする考えもあるが、 それだとせっかく苦労して Traitsを導入しようとしているのが まったく無駄になるので、名 前を書き換えたメソッド呼び出しを モジュールのメソッド定義実 体から探し出してメソッドをコピーする という(Bertrand Mayer のOOSCに記述されていたアイディア)を導入することを考える これも試しましょう。 module Foo def m :Foo end def x self.m end end module Bar def m :Bar end def y self.m end end class Baz mix Foo, :m => :m_f mix Bar, :m => :m_b end obj = Baz.new p obj.x するとFoo#xの中で呼ばれたmはすでにリネームされて存在しないの でエラーになります。しかし、これはインクルード時にメソッドxの 本体を(コピーした上で)書き換えて、mの代わりにリネームされた m_fを呼ぶべきかもしれません。あるいは、現状通り、そんなことは しないというのもひとつの考えです。