From: Kouhei Sutou Date: 2006-11-07T10:56:29+09:00 Subject: [ruby-dev:29888] Re: Module duplicate 須藤です. 06/11/06 に SASADA Koichi さんは書きました: > これは、どう判断するべきですかね。今回みたいに対応するべき問題なのか、 > 仕様が前の方がいいのか。須藤さん、これについてなんか意見ありませんか? 私は,同じメソッドが2回呼ばれるのが気持ち悪いので今までの仕様の方が いいです.ただ,1.9の仕様でも2回呼ばれないようにソースコードを(おそ らく簡単に)修正できると思うので,そんなに強く主張できないです. 今までの仕様だと嬉しいコード例をあげます.アプリケーションクラスに, Moduleをincludeしていくことによって機能を追加していく,というのを想定 しています. module ExtBase attr_reader :exts # Moduleでinitializeを定義するときはどこに挟まってもいいように # 引数を丸投げして自分の分を初期化するコードを書くことが多い # です. def initialize(*args, &block) super @exts = [] end end module ExtA include ExtBase def initialize(*args, &block) super @exts << :a end end module ExtB include ExtBase def initialize(*args, &block) super @exts << :b end end class Base def initialize(...) ... end end class App < Base include ExtA include ExtB def initialize(...) super ... end end 1.9だとこうなるんですよね? p App.new.exts # => [:b] そして,おそらくこのように変更すればよいのですよね? module ExtA def initialize(*args, &block) super @exts << :a end end module ExtB def initialize(*args, &block) super @exts << :b end end class App < Base include ExtBase include ExtA include ExtB def initialize(...) super ... end end 私は書き直したやつよりも,書き直す前のやつの方が好きです.理由は ExtBaseに依存しているのはExtAとExtBなので,includeはAppじゃなくて そっちに書きたい からです. 消極的な理由は以下の通りです. * ExtA/ExtBを使うためには事前にExtBaseをincludeしておく必要があると いうのは,忘れてしまいそうで嫌. # ドキュメントでなんとでもなる * 拡張無しの状態に変更するために,include ExtA/ExtBだけではなく include ExtBaseもコメントアウトしなければいけないのが手間. * 逆に,拡張無しの状態から拡張機能Aを追加するために,include ExtA だけじゃなく,include ExtBaseも書かなければいけないのが嫌. Moduleでのsuper禁止は冗談だと思いますが,一応,強く否定しておきます. 理由は上記のようなModule毎に初期化するというような場合,includeするク ラス側で明示的に各Moduleの初期化メソッドを呼び出すといったことをしな ければなくなるからです. module ExtA def init_ext_a ... end end module ExtB def init_ext_b ... end end class App def initialize ... init_ext_a init_ext_b end end