【问题标题】:How to dynamically define all instance methods of class in module?如何动态定义模块中类的所有实例方法?
【发布时间】:2015-01-02 09:44:52
【问题描述】:

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

我正在使用带有 RoR 的 Ruby ruby 2.1.3p242

【问题讨论】:

  • 你想要C类的实例方法然后简单地做C.instance_methods
  • 好的。但我怎么知道是C 还是SomeOtherClassWhichModuleIsIncluded
  • C.ancestors.select {|o| o.class == Module }
  • include_modules
  • 如果可以在module中动态定义some方法..请在回答中填写。

标签: ruby-on-rails ruby


【解决方案1】:

这里是基于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 行之后声明的方法才会被拦截。

【讨论】:

    猜你喜欢
    • 2013-04-30
    • 2012-06-30
    • 2012-07-04
    • 2011-07-14
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多