From: Minero Aoki Date: 2002-03-08T16:40:53+09:00 Subject: [ruby-dev:16273] Re: pstore.rb and sync.rb あおきです。 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 を たどってチェック……というコストをなくせる) ------------------------------------------------------------------- 青木峰郎