将块常量复制到模块中

Copy block constants into module

我正在尝试定义一个 DSL,其中一些常量是在一个块中定义的,并且必须被复制到一个新制作的模块中。到目前为止我得到了这个:

class Foo
  def self.macros(&block)
    mod = Module.new do
      module_eval &block
    end
    self.const_set(:Macros, mod)
  end

  macros do
    Point = Struct.new :x, :y
    VALUE = 5

    def self.bar 
      "bar"
    end

    def foo
      "foo"
    end
  end
end

使用上面的代码我设法得到 Foo::Macros.bar 但是常量丢失了。

如何获取块中定义的常量?

我想通过 class 中嵌入的新模块访问它们,例如 Foo::Macros::Point

Ruby 常量查找规则不会随着 class_evalmodule_eval 而改变,因此您不能使 Foo 中块中定义的常量成为 Foo::Macros, 遗憾的是.


简单:

Foo::Value
Foo::Point

Foo::Macros只是你定义的匿名模块的别名,它不会改变定义对象的范围。

如果你先定义模块,你可以使用const_get访问它:

module Test
end
Test.module_eval do
  ANSWER = 42
end
Test.const_get('ANSWER')
=> 42