maeshimaの日記

メモ書きです

メタプログラミングRuby 4章

カレントクラス

カレントクラスはカレントオブジェクト(self)とは別。Rubyのプログラムは常にカレントオブジェクトとカレントクラスを持っている。メソッドを定義したときに、そのメソッドはカレントクラスのインスタンスメソッドになる。

class MyClass
  def method_one
    def method_two; 'Hello!'; end
  end
end

method_two が定義されたときのカレントクラスは self のクラスである MyClass

class_eval と instance_eval の違い

  • class_eval は、self とカレントクラスをレシーバにする。
  • instance_eval は、self をレシーバにし、カレントクラスをレシーバの特異クラスにする。

class_eval と class ... end の違い

  • class は定数が必要だけど、class_eval はクラスを参照する変数なら何でも使える
  • class は新しいスコープをオープンする。class_eval はフラットスコープを持つ

class キーワードを使わずにクラスを定義する

Class.new を使えばOK。

特異メソッド

既存のクラスを少しいじったインスタンスを使いたいけど、継承したりするには大げさなときに使えるっぽい。

特異クラス

  • メソッド探索は、オブジェクトの右(クラス)に進み、そこから継承関係を上に辿っていく。
  • 特異メソッドを定義すると、オブジェクトの一つ右が特異クラスになり、その上がオブジェクトのクラスになる
  • オブジェクトがクラスだった場合は特殊。特異クラスの上はスーパークラスの特異クラスになり、BasicObjectの特異クラスの上は Class クラスになる。

メソッドエイリアス、アラウンドエイリアス

alias や alias_method で既存のメソッドのエイリアスを作り、その後既存のメソッドを修正する。モンキーパッチをあてるだけよりかは、元のメソッドを残しているのでいくらか良心的。でも結局は既存のメソッドを直接修正することになるので影響範囲をよく見て使う必要がありそう。