オブジェクトの特異メソッドを定義するよりもモジュールをextendしよう

Jay Fields' Thoughts: Extend modules instead of defining methods on a metaclass

特異メソッドを直接定義するのではなくて、可能な限りモジュールをextendしよう。そうしたほうが柔軟性が高まるというお話。
当たり前の話なんだが、言われてみるまで気がつかなかった俺。

直接特異メソッドを定義すると、後から振舞いを再定義することができない。

obj = Object.new
def obj.hello_world
  "hello"
end

obj.hello_world # => "hello"

module Spanish
  def hello_world
    "hola"
  end
end

obj.extend Spanish
obj.hello_world # => "hello"

一方、extendすることで振舞いを再定義することができる。

obj = Object.new

module English
  def hello_world
    "hello"
  end
end

obj.extend English
obj.hello_world # => "hello"

module Spanish
  def hello_world
    "hola"
  end
end

obj.extend Spanish
obj.hello_world # => "hola"

つまり、

Object
  |
<objのメタクラス>(ここでhelloを定義していたため、extendで振舞いを変更できなかった)

だったのを、次のように変更した。

Object
  |
  +<----English.hello
  |
<objのメタクラス>

から

Object
  |
  +<----English.hello
  |
  +<----Spanish.hello
  |
<objのメタクラス>

ってな継承構造になるため、Spanishのメソッドが呼ばれるという寸法。