あおきです。

  In mail "[ruby-dev:16270] Re: pstore.rb and sync.rb"
    matz / ruby-lang.org (Yukihiro Matsumoto) wrote:

> まつもと ゆきひろです

> たぶん、するならKernel.initialize_for()をなにもしないメソッ
> ドにしておいて、それを呼ぶという実装にすると思います。

メソッドではなくブロックにして、オブジェクト側で instance_eval
するのはどうでしょうか。たとえばモジュール側では

  module M
    module_initializer {
        @ivar = 'ok'
    }
  end

のように定義します。このブロックをモジュールに保存しておき、
オブジェクト側から ancestors の初期化ブロックをまとめて呼びます。
Ruby で定義するとこんな感じ。

  class Object
    def self.new( *args, &block )
      obj = malloc(...)
      obj.__send__ :initialize, *args, &block
      obj.__send__ :__module_initialize__
      obj
    end

    private

    def __module_initialize__
      self.class.ancestors.reverse_each do |mod|
        next unless mod.class == Module   # reject classes
        block = mod.initializer
        instance_eval(&block) if block
      end
    end
  end

  class Module
    def module_initializer( &block )
      @initializer = block
    end

    attr_reader :initializer
  end


利点は三点です。

  * 初期化ブロック定義のインターフェイスがメソッドなので、
    定義を簡単に (かつ特別扱いすることなく) 検知できる。

  * module_function では、モジュール自体と include した
    オブジェクトの両方を同じように初期化したいことがある。
    ブロックならば使いまわし可能。

  * ブロックならば先に集めておくことができる。
    (オブジェクト生成のたびに ancestors を
     たどってチェック……というコストをなくせる)

-------------------------------------------------------------------
青木峰郎