2016-06-14 80 views
5

我有一个模块,其中包含类名为String(其中包括)。我需要按名称查找类,并优雅地退后来,如果没有这样的类。是否有可能缩小红宝石不断查找

module Mod1 
    module String 
    end 
end 
Mod1.const_get 'String' 
#⇒ Mod1::String 
Kernel.const_get '::Mod1::String' 
#⇒ Mod1::String 

到目前为止,这么好。当我尝试查找不存在的类时,我预计会收到NameError,这很好。问题是,如果没有与现有的全局命名空间给定名称一类,它被返回:

Mod1.const_get 'Fixnum' 
#⇒ Fixnum < Integer 
Kernel.const_get '::Mod1::Fixnum' 
#⇒ Fixnum < Integer 

我理解的原因,但我的问题是:有一个不折不扣的只能在给定名称空间中查找常量的方法?

现在我请与

result.to_s.start_with?(namespace) 

的结果,但这绝对不是缩小查找奇的方式。

回答

7

答案是:

Mod1.const_get 'Fixnum', false 

这里的DOC:

/* 
* call-seq: 
*  mod.const_get(sym, inherit=true) -> obj 
*  mod.const_get(str, inherit=true) -> obj 
* 
* Checks for a constant with the given name in <i>mod</i>. 
* If +inherit+ is set, the lookup will also search 
* the ancestors (and +Object+ if <i>mod</i> is a +Module+). 
* 
* The value of the constant is returned if a definition is found, 
* otherwise a +NameError+ is raised. 
* 
*  Math.const_get(:PI) #=> 3.14159265358979 
* 
* This method will recursively look up constant names if a namespaced 
* class name is provided. For example: 
* 
*  module Foo; class Bar; end end 
*  Object.const_get 'Foo::Bar' 
* 
* The +inherit+ flag is respected on each lookup. For example: 
* 
*  module Foo 
*  class Bar 
*   VAL = 10 
*  end 
* 
*  class Baz < Bar; end 
*  end 
* 
*  Object.const_get 'Foo::Baz::VAL'   # => 10 
*  Object.const_get 'Foo::Baz::VAL', false # => NameError 
* 
* If the argument is not a valid constant name a +NameError+ will be 
* raised with a warning "wrong constant name". 
* 
* Object.const_get 'foobar' #=> NameError: wrong constant name foobar 
* 
*/ 

https://github.com/ruby/ruby/blob/449fbfd4d4ce47be227804c22214fed32a5b0124/object.c#L2027

+1

完美,谢谢。明显的建议“看看方法文档”照常工作。 – mudasobwa

+0

我可能建议链接到文档而不是MRI源? http://ruby-doc.org/core-2.3.1/Module.html#method-i-const_get –