From: shugo@... (Shugo Maeda) Date: 1997-10-11T03:22:39+09:00 Subject: [ruby-list:4891] mixin - singleton method inheritance, const etc... 前田です。 前もちょっと考えたのですが attr :foo, TRUE, "default value" としたいと思って試してみました。 --------------------- 1). module AttrInitMixinE def AttrInitMixinE.extend_object(klass) result = super(klass) klass.module_eval 'ATTR_DEFAULTS = Hash.new' return result end def attr(name, writable = FALSE, default = nil) result = super(name, writable) if name.instance_of? Fixnum name = name.id2name end self::ATTR_DEFAULTS[name] = default return result end def new(*args) result = super result.instance_eval %q[ ATTR_DEFAULTS.each do |name, default| eval "@#{name} = default" end ] return result end end class Foo extend AttrInitMixinE attr :foo, TRUE, "default value" end --------------------- 2). module AttrInitMixinI def AttrInitMixinI.append_features(klass) result = super(klass) klass.module_eval %q{ ATTR_DEFAULTS = Hash.new def klass.attr(name, writable = FALSE, default = nil) super(name, writable) if name.instance_of? Fixnum name = name.id2name end ATTR_DEFAULTS[name] = default end } return result end def initialize(*args) super type::ATTR_DEFAULTS.each do |name, default| eval "@#{name} = default" end end end class Foo include AttrInitMixinI attr :foo, TRUE, "default value" end --------------------- 1はextendするパターンで2はincludeするパターンです。 モジュールのユーザーにとって,1のようにクラスをextendするのは ちょっとわかりにくいのかなと思うのですが,どうなんでしょう。 # 石塚さんはクラスのextendを多用されていそうですが(^^; でも2だとappend_featuresの中でメソッド定義しているのがちょっと 苦しげですし,1.1でしか動きませんよね。 で,ここからが本題です。 includeで特異メソッドも継承されると,2みたいなのをもっときれい に書けると思うのですが,includeで特異メソッドが継承されないの はなぜでしょう。普通の継承では特異メソッドも継承されるのでinclude でも継承されるとうれしいのですが,やはり何か問題があるのでしょうか。 1)のattrではself::ATTR_DEFAULTS,2)のinitializeではtype::ATTR_DEFAULTS としないとNameErrorになるのですが,これはこういうものなのでしょうか。 -- 前田 修吾