我有一个模块,其中包含名为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)
但这绝对不是缩小查找范围的最佳方式.
解决方法@H_301_18@
答案是:
Mod1.const_get 'Fixnum',false
这是文档:
/*
* 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
Mod1.const_get 'Fixnum',false
这是文档:
/* * 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