ruby のメソッド呼び出しと method_missing

Ruby で特定のクラスのインスタンスに対してメソッドを呼び出した時、まずはクラスに存在しているインスタンスメソッドから探す。 そのクラスに該当のインスタンスメソッドがなければ、継承チェーンを上ってインスタンスメソッドを探す。 例えば下記のようなクラスがあったとする。

class Neko
  def nyaa
    "Miaumiau"
  end
end

このクラスのインスタンスをレシーバとしてメソッドを呼び出すと Neko -> Object -> Kernel -> BasicObject の順でメソッド探索が行われる(継承チェーン)

> Neko.ancestors
=> [Neko, Object, Kernel, BasicObject]

このクラスのインスタンスをレシーバとしていくつかメソッド呼び出しを行ってみる

f:id:nekootoko3:20191127000728p:plain

f:id:nekootoko3:20191127001222p:plain

f:id:nekootoko3:20191127001244p:plain

f:id:nekootoko3:20191127001259p:plain

Neko クラスをオープンして #method_missing を定義する(オープンクラス)

class Neko
  def method_missing(nakigoe)
    [:wanwan, :uho].include?(nakigoe) ? nakigoe.to_s : super
  end
end

f:id:nekootoko3:20191127001417p:plain

f:id:nekootoko3:20191127001434p:plain

method_missing を上手く使うと、メソッド呼び出しを捕まえてコードの共通化を図れる。
しかし、可読性・保守性が落ちてしまうこともあるので注意が必要。

参考文献