2015-01-26 52 views
2

我想定义一个块,在块中定义了一些常量并且必须复制到新建模块中。我得到这个至今:将块常量复制到模块中

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但常量失踪。

如何获得块内定义的常量?

我想通过嵌入在类内的新模块来访问它们,就像Foo::Macros::Point

+0

作为一个说明,常数通常是'ALL_CAPS'地方类和模块是'MixedCase'。 – tadman 2015-01-26 18:48:57

+0

刚更新了这个例子。还注意到无法在模块内部初始化Struct或Classes。似乎在模块中评估的唯一东西是函数定义 – SystematicFrank 2015-01-26 18:57:40

+0

您可能在使用此方法时遇到问题,因此声明块内的常量非常不规则。我倾向于用'const_set'更具体地阐明它,或者找到一种不涉及使用常量的方法,而是声明方法。 – tadman 2015-01-26 19:12:05

回答

1

红宝石不断查找规则不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 
+0

啊!所以他们在那里。但实际上,因为我在Module.new内部进行了评估,所以我期望这些常量在模块内部,而不是包含在我的类中。那可能吗?像Foo :: Macros :: Point – SystematicFrank 2015-01-26 18:14:49

+0

尝试先定义Foo :: Macros,然后module_eval块内,它应该工作 – Geoffroy 2015-01-26 18:16:35

+0

我试着你的代码里面的函数,并得到一个错误关于'动态常量赋值'外类函数工程,但我仍然希望DSL将这些常量打包到新模块中。以下是我到目前为止所尝试的内容:https://gist.github.com/fgarcia/0f566ea9313794e19db0 – SystematicFrank 2015-01-26 18:29:05