2014年4月2日水曜日

has-a関係でmethod_missingを使う


上図のように、クラス間が「has-a関係」になっている場合、Noodleクラス側からSoupクラスの属性を参照するには、
irb(main):001:0> Noodle.first.soup.aji
=> "こってり"
のようにして、包含しているSoupクラスを毎回指定する必要がある。

Soupクラスの属性がNoodleクラスの属性であるかのように見せるためには、
  def aji
    return soup.aji
  end
irb(main):003:0> Noodle.first.aji
=> "こってり"
のように、Noodleクラス側でSoupクラスの属性を返すメソッドを実装すれば良いだのだが、属性の数が多いと面倒である。

そこで下記のように、method_missingというメソッドを使って、Noodleクラスに存在しない属性が参照された場合は自動的にSoupクラスの属性を参照して返すように記述すると、
  def method_missing(method, *args)
    eval("soup." + method.to_s)
  end
irb(main):006:0* Noodle.first.aji
=> "こってり"
Soupクラスの属性すべてがSoupクラスを指定しなくても参照できるようになった。