【问题标题】:Module_eval in ruby. Metaprogramming, macros and modulesruby 中的 Module_eval。元编程、宏和模块
【发布时间】:2014-02-04 13:25:10
【问题描述】:

请帮助我了解如何在 ruby​​ 中使用方法 module_eval。我对如何以适当的方式将模块 m 包含在类 P 中很感兴趣。看来,我的 include 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

提前致谢!

【问题讨论】:

  • 您希望将模块添加到哪个类?
  • 我希望在 P 类中添加模块 m
  • 你为什么不改用#class_eval呢?或者你需要#module_eval
  • 根据您的代码,Module 在评估后似乎也没有回复:foobar

标签: ruby-on-rails ruby metaprogramming


【解决方案1】:

非常感谢您的提示,我在这种情况下找到了两种解决方案。首先使用 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2017-06-21
    • 1970-01-01
    相关资源
    最近更新 更多