クラス メソッドとインスタンス メソッドの両方を含めたい Ruby クラスがあります。hereで説明されているパターンに従って、現在次のものを使用しています。
class SomeObject
include SomeObject::Ability
def self.some_builder_method(params)
# use some_class_method ...
end
end
module SomeObject::Ability
module ClassMethods
def some_class_method(param)
# ...
end
end
def self.included(klass)
klass.extend(ClassMethods)
end
def some_instance_method
# ...
end
end
モジュール内のすべてのメソッドが論理的に適合するため、2 つの別個のモジュール (1 つは組み込み、もう 1 つは拡張) を作成したくありません。一方、このパターンでは、a) 追加のClassMethods
モジュールを定義する必要があり、b) すべてのモジュールに対してボイラープレートself.included
メソッドを記述する必要があります。
これを行うより良い方法はありますか?
編集 1 : 別の方法を見つけましたが、これが最初の方法よりも優れているかどうかはわかりません。
module Concern
def included(base)
# Define instance methods.
instance_methods.each do |m|
defn = instance_method(m)
base.class_eval { define_method(m, defn) }
end
# Define class methods.
(self.methods - Module.methods).each do |m|
unless m == __method__
base.define_singleton_method(m, &method(m))
end
end
end
end
module SomeModule
extend Concern
def self.class_m
puts "Class"
end
def instance_m
puts "Instance"
end
end
class Allo
include SomeModule
end
Allo.class_m # => "Class"
Allo.new.instance_m # => "Instance"