メタプログラミング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章は読み終えました。