如何从 Ruby 模块的包含钩子访问 class 方法

How to access class method from the included hook of a Ruby module

我希望我的模块根据其包含的 class' 实例方法定义新的实例方法。但是在 included 钩子中,class 方法还没有定义(因为模块包含在 class 的顶部,在 class 方法被定义之前):

module MyModule
    def self.included(includer)
        puts includer.instance_methods.include? :my_class_method # false <- Problem
    end
end

class MyClass
    include MyModule
    def my_class_method
    end
end

我希望该模块的用户可以自由地将其包含在他们 class 的顶部。

有没有办法让模块为 class 定义额外的方法?

注意:如果有其他方法可以实现此目的,我不必使用 included 挂钩。

您可以使用 method_added 回调:

module MyModule
  def self.included(includer)
    def includer.method_added(name)
      puts "Method added #{name.inspect}"
    end
  end
end

class MyClass
  include MyModule

  def foo ; end
end

输出:

Method added :foo

如果您想跟踪现有和未来的方法,您可能需要这样的东西:

module MyModule
  def self.on_method(name)
    puts "Method #{name.inspect}"
  end

  def self.included(includer)
    includer.instance_methods(false).each do |name|
      on_method(name)
    end

    def includer.method_added(name)
      MyModule.on_method(name)
    end
  end
end

示例:

class MyClass
  def foo ; end

  include MyModule

  def bar; end
end

# Method :foo
# Method :bar