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

时间:2015-01-02 09:44:52

标签: ruby-on-rails ruby

我想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

1 个答案:

答案 0 :(得分:0)

以下是基于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挂钩来拦截扩展类中的新方法,然后使用面向方面的代码重新定义它们。

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