ちなみに

火曜日の空は僕を押しつぶした。

Module#define_methodの挙動(タイトルが思いつかなかった)

クラス階層関連-ohai日誌を読んでいて、

def self.included(base)
  class << base
    private :new
    _instance = nil
    def instance
      _instance ||= new
    end
  end
end

じゃダメなの?と思ったら、ダメだった。
冷静に考えると当然で、この書き方だとinstanceを呼んだ時点で別の_instanceが生成されて、newが実行されるので結局毎回違うインスタンスが生成されてしまうのだ。
この書き方でいくならば、_instanceをクラス変数にしなくてはいけない。
では、なぜdefine_methodならうまくいくのか。

インスタンスメソッド name を定義します。
ブロックを与えた場合、定義したメソッドの実行時にブロックがレシーバクラスのインスタンスの上で Object#instance_eval されます。

502 Bad Gateway

ということで、定義するのではなくて、実行時に渡して置いたブロックをinstance_evalするのだそうで、つまり、ブロックは定義した時のコンテキストを保持しているわけです。(最近やっとクロージャとかレキシカルとかが分かってきた)
なので、instanceを呼んだ時の_instanceは、定義時の_instanceであって、それはつまり何度instanceを呼ぼうと同じ_instanceを用いると言うことなのです。はい。

なるほどー。


Rubyの勉強より中間発表の準備をしましょう > 自分