Techioz Blog

同じモジュールからクラスメソッドとインスタンスメソッドを追加できますか?

概要

初心者の質問:

include と extend がどのように機能するかはわかっていますが、私が疑問に思っているのは、単一のモジュールからクラス メソッドとインスタンス メソッドの両方を取得する方法があるかどうかということです。

2 つのモジュールを使用してこれを行う方法は次のとおりです。

module InstanceMethods
    def mod1
        "mod1"
    end
end

module ClassMethods
    def mod2
        "mod2"
    end
end

class Testing
    include InstanceMethods
    extend ClassMethods 
end

t = Testing.new
puts t.mod1
puts Testing::mod2

お時間を割いていただきありがとうございます…

解決策

それを表す一般的な慣用句があります。付属のオブジェクト モデル フックを利用します。このフックは、モジュールがモジュール/クラスに含まれるたびに呼び出されます。

module MyExtensions
  def self.included(base)
    # base is our target class. Invoke `extend` on it and pass nested module with class methods.
    base.extend ClassMethods
  end

  def mod1
    "mod1"
  end

  module ClassMethods
    def mod2
      "mod2"
    end
  end
end

class Testing
  include MyExtensions
end

t = Testing.new
puts t.mod1
puts Testing::mod2
# >> mod1
# >> mod2

私は個人的に、インスタンス メソッドをネストされたモジュールにグループ化することも好みます。しかし、私の知る限り、これはあまり受け入れられていない習慣です。

module MyExtensions
  def self.included(base)
    base.extend ClassMethods
    base.include(InstanceMethods)

    # or this, if you have an old ruby and the line above doesn't work
    # base.send :include, InstanceMethods
  end

  module InstanceMethods
    def mod1
      "mod1"
    end
  end

  module ClassMethods
    def mod2
      "mod2"
    end
  end
end