メタプログラミングRuby 第1章 月曜日:オブジェクトモデル その3

第1章を読み終えました

  • メソッドの探索「一歩右へ、それから上へ」
  • 継承ツリー
    • Module を include した時の継承ツリーへの影響についての解説で「インクルードクラス(またはプロキシクラス)」としてモジュールをラッパしたクラスが挿入されると解説されています。これは IClass のことを指しているのだとおもいますが、ここではこの説明は不要で、単にモジュールが挿入されると言えばいいと思います。IClass の存在理由は CRuby が継承ツリーを linked list で実現しているので、モジュールをそのまま繋げようとすると色々な場所に挿入できない、という実装上の要請からくるものなので、CRuby の実装を読み解くための解説でなく Ruby のオブジェクトモデルを理解するだけの目的なら IClass の存在について言及する必要はないと思います。
  • コラムで、private メソッドについて
    • わざと無視しているだけだと思いますが、private メソッドはインスタンスメソッドの外から呼べない、というのはもちろん建前で、呼ぼうと思えば呼べます。いくつか呼ぶ方法を考えてみました。
class A
  def m1
    :m1
  end
  private :m1
end
a = A.new
      • send を使う
a.send(:m1)
      • instance_eval を使う
a.instance_eval{ m1 }
a.instance_eval("m1")
      • Object#method で Method オブジェクトを取り出して呼ぶ
a.method(:m1).call
      • Class#instance_method で UnboundMethod を取り出して bind して呼ぶ
A.instance_method(:m1).bind(a).call
      • m1 を呼ぶ特異メソッドを定義してそれを経由して呼ぶ
class << a
  def m2
    m1
  end
end
a.m2
      • m1 の alias を作ってそれを public にして呼ぶ
A.module_eval{ alias m2 m1; public :m2 }
a.m2
      • もういっそ m1 を public にしてしまって呼ぶ
A.module_eval{ public :m1 }
a.m1

後半はやりすぎというかただの冗談ですが、いろいろ方法がありますね。

これで第1章は読み終えました。