RubyのRefinements拡張

Rubyはモンキーパッチが簡単にできてしまうが、多用するとコードの複雑性が増してトレースが困難になるため、基本的に世の中一般のプロジェクトでは禁止されている(はず)。 それでも実装を進めていて拡張したほうが汎用性が増すケースもある。その場合はよく Refinements を使用している。

配列内の数値について平均を求める場合、以下のようになるが、

array = [1, 2, 3, 4]
array.sum / array.length.to_f

この処理をメソッドとして分離したとしても、引数として配列を渡すのがどうにもしっくりこないと感じているため、 refine Array を行うmoduleを作成して、定義が必要なクラスでのみ呼び出すようにしている。

def average(array)
  array.sum / array.length.to_f
end
module ArrayEx
  refine Array do
    def average
      sum / length.to_f
    end
  end
end

using ArrayEx

[1, 2, 3, 4].average