method_missing と instance_eval を使った Decorator
Kernel#method_missing を使ってみたいです。
method_missing は、任意のクラスに対してメソッドが呼び出されたとき、対象のメソッドがそのクラスのクラス階層のどこにも実装されてなかった場合に呼び出されるメソッド、だそうです。Perl の AUTOLOAD に似ています。
そこで、method_missing を使った Decorator パターンを実装してみました。Dog オブジェクトを渡すとその犬が強くなる StrongDog です。
dog = Dog.new('ポチ') sdog = StrongDog.new(dog) dog.bark sdog.bark
という風に使います。すると、
ポチ: わんわん ポチ+1: brrr... ポチ+1: わんわん
という風な結果が返ります。Decorator の StrongDog でくるむと +1 されて(ロングソード+1、のようなイメージです)、威勢がよくなります。クラスの実装は以下のようにしてみました。
class Dog attr :name def initialize(name) @name = name end def bark puts "#@name: わんわん" end end class StrongDog def initialize(dog) @dog = dog @dog.name << "+1" end def method_missing(method_id) puts "#{@dog.name}: brrr..." @dog.instance_eval(method_id.id2name) end end
StrongDog#bark は実装していないので、それが呼び出されると method_missing が呼び出され、前処理を挟んだあと @dog に同名のメソッドに処理を転送します。
instance_eval の理解がまだ不完全ですが、なんとなく使ってみたらうまくいきました。