ruby中的Module_eval。元编程,宏和模块

时间:2014-02-04 13:25:10

标签: ruby-on-rails ruby metaprogramming

请帮助我了解如何在ruby中使用方法module_eval。我感兴趣的是如何以适当的方式在P类中包含模块m。看来,我的包含m不起作用,但我无法理解为什么。

请考虑以下代码:

module Mod
  def self.included(klass)
    klass.extend(Class_methods)
  end

  module Class_methods 
    def foo
      m = Module.new
      m.module_eval(%Q{
        def foobar
          "foobar"
        end
      })
      include m
    end
  end
end

P = Struct.new(:x, :y) do include Mod end

class << P 
  def method_name
    "q"
  end
end

p P.respond_to?(:foo)
p P.respond_to?(:foobar)

P.foo
p P.respond_to?(:foobar)

输出:

true
false
false

提前致谢!

1 个答案:

答案 0 :(得分:0)

非常感谢您的提示,我在这种情况下找到了两种解决方案。首先是class_eval,第二个是module_eval但是使用'extend m'而不是'include m'

1)使用class_eval

module Mod
  def self.included(klass)
    klass.extend(Class_methods)
  end

  module Class_methods 
    def foo
      self.class_eval(%Q{
        def self.foobar
          "foobar"
        end
      })
    end
  end
end

P = Struct.new(:x, :y) do include Mod end

class << P 
  def method_name
    "q"
  end
end

p P.respond_to?(:foo)
p P.respond_to?(:foobar)

P.foo
p P.respond_to?(:foobar)

输出:

true
false
true

2)使用module_eval:

module Mod
  def self.included(klass)
    klass.extend(Class_methods)
  end

  module Class_methods 
    def foo
      m = Module.new
      m.module_eval(%Q{
        def foobar
          "foobar"
        end
      })
      extend m
    end
  end
end

P = Struct.new(:x, :y) do include Mod end

class << P 
  def method_name
    "q"
  end
end

p P.respond_to?(:foo)
p P.respond_to?(:foobar)

P.foo
p P.respond_to?(:foobar)