モジュールの特異メソッドをincludeして使う(修正)

以前の記事が恐ろしく分かりにくいので、軽くまとめ直す。

module A
  def instance_method_of_a
    puts "A#instance_method_of_a was called."
  end

  module ClassMethods
    # A::ClassMethodsで定義されたインスタンスメソッドは、
    # Aをincludeしたクラスのクラスメソッドとして利用できる
    def class_method_of_a
      puts "A::ClassMethods.class_method_of_a was called. Not A.a_class_method!"
    end
  end
  
  def self.included(mod)
    # ModuleのインスタンスmodがAをincludeした際に呼び出され、
    # A::ClassMethodsのインスタンスメソッドをmodに特異メソッドとして追加する。
    mod.extend ClassMethods
  end
end

class B
  include A
end

使ってみると、

B.class_method_of_a
# A::ClassMethods.class_method_of_a was called. Not A.class_method_of_a!
b = B.new
b.instance_method_of_a
# A#instance_method_of_a was called.

これを上手く使って機能ごとにモジュールで名前空間を設定し、かつファイルも分割できれば開発しやすいだろうなぁと思う。Railsがまさにそんな感じ。その代わり管理が大変だけど。