如何在模块中动态定义class的所有实例方法?

How to dynamically define all instance methods of class in module?

我想prepend(或include)一些模块进入class。该模块应动态定义 class 中定义的所有实例方法并进行一些自定义。这可能吗?

像这样

   Module M
     klass_methods = get_instance_methods_of(classname) 
     // get_instance_methods_of is available to me.
     // So, getting the methods is not a  problem. 
     // But i have to pass class name


     klass_methods.each do |m|
        define_method m do
          puts "from module"
          super
        end
     end
   end

  Class C
    prepend M
    def some
       puts "from class"
    end
  end

$ C.new.some
>> from module
>> from class

可能吗?

如果你想知道更多我想做的事情,你可以在这里阅读https://github.com/elabs/pundit/issues/244

我正在使用 Ruby ruby 2.1.3p242 和 RoR

这是一个基于this答案的解决方案:

module M
  def method_added(meth)
    return if @recursing
    @recursing = true
    old_meth = instance_method(meth)
    define_method(meth) do |*args, &block|
      puts 'from module'
      old_meth.bind(self).call(*args, &block)
    end
    @recursing = nil
  end
end

class C
  extend M
  def some
    puts "from class"
  end
end

C.new.some
# from module
# from class

此解决方案使用method_added 钩子来拦截扩展class 中的新方法,然后用面向方面的代码重新定义它们。

请注意,只有在 extend M 之后 声明的方法才会被拦截。