class Foo
end
class_name = 'Foo'
f = eval(class_name).new
#<Foo:0x007fd3e273ed68>
此示例创建Foo的预期实例。
期望定义该类,但我们想要实例化class_name
中定义的类的对象。
class_name
的值来自用户,因此上面的代码是一个非常糟糕的想法...
答案 0 :(得分:2)
class Foo
end
class_name = 'Foo'
myClass = Module.const_get(class_name)
myClass.new
当然,顾名思义,您可以使用它来获得任何类型的常量。因此,检查一下你是否回到课堂可能是明智的:
SOME_CONST = 5
Module.const_get('SOME_CONST').is_a? Class # => false
Module.const_get('String').is_a? Class # => true
答案 1 :(得分:1)
const_get
可以获得对Class
Module.const_get( :Foo ).new
或
Module.const_get( 'Foo' ).new
注意:在&lt; 1.9它只搜索当前模块。
答案 2 :(得分:1)
一堂课没什么特别的。它只是一个分配给变量的对象,或者在您显示的代码的情况下,是一个常量。因此,您可以使用相同的元编程方法从变量中检索类,就像使用任何其他对象一样:Object#instance_variable_get
,Module#class_variable_get
,Binding#local_variable_get
,Thread#thread_variable_get
或在这种情况下适用的Module#const_get
:
class Foo; end
class_name = 'Foo'
foo = Object.const_get(class_name).new
#=> #<Foo:0x007fd3e273ed68>
foo = self.class.const_get(class_name).new
#=> #<Foo:0x007fd3e273ed68>
请注意,其他两个答案中的代码只会偶然发生:它们会在Foo
类的上下文中查找Module
,这只会有效,因为您实际上 Foo
中定义的Object
和Module
的{{1}}继承自Object
。如果您已将Foo
定义为不在祖先中,而是在Module
的兄弟中,那么其他两个答案中的代码将不起作用:
module Bar; class Foo; end end
Module.const_get(:Foo)
# NameError: uninitialized constant Module::Foo
Bar.const_get(:Foo)
# => Bar::Foo
如果你希望const_get
的行为与普通的常量查找相同,你需要在想要实际查找它的类/模块上调用它,而不是在一些随机类中。