如何使用ruby中的字符串名称创建类实例?


121

我有一个类的名称,我想创建该类的实例,以便可以遍历该类的架构中存在的每个rails属性。

我将如何去做?

  1. 我的名字是我要检查的类的字符串
  2. 我想我需要实例化一个类实例,以便我可以
  3. 循环浏览其属性并打印它们。

1
这是一个很好的问题。感谢您提出要求并让我免于使用eval
David West

Answers:


219

在rails中,您可以执行以下操作:

clazz = 'ExampleClass'.constantize

在纯红宝石中:

clazz = Object.const_get('ExampleClass')

带有模块:

module Foo
  class Bar
  end
end

你会用

> clazz = 'Foo::Bar'.split('::').inject(Object) {|o,c| o.const_get c}
  => Foo::Bar 
> clazz.new
  => #<Foo::Bar:0x0000010110a4f8> 

4
请注意,这Object.const_get('Foo::Bar')将不起作用,而constantize会。
马克-安德烈·Lafortune

谢谢,由于Admin :: User问题,醒来询问这件事:)打败我。
mhenrixon

嘿@Wes,这很有帮助,谢谢!快速问题-嵌套模块也可以使用吗?例如,clazz = 'Foo::Bar::Uber'
iaacp

@iaacp是的,它将与您使用的嵌套级别一样多。
2015年


6

试试这个:

Kernel.const_get("MyClass").new

然后循环遍历对象的实例变量:

obj.instance_variables.each do |v|
  # do something
end

谢谢,由于我真的必须遍历活动记录模型的列,因此这对我而言不起作用,但对我的“纯”红宝石应用程序将非常有用:)
mhenrixon 2011年

1
检出ActiveRecord#attributes()和/或ActiveRecord#attribute_names()。
mbreining 2011年


5
module One
  module Two
    class Three
      def say_hi
        puts "say hi"
      end
    end
  end
end

one = Object.const_get "One"

puts one.class # => Module

three = One::Two.const_get "Three"

puts three.class # => Class

three.new.say_hi # => "say hi"

在ruby 2.0和可能的较早发行版中,Object.const_get递归地在诸如的名称空间上执行查找Foo::Bar。上面的示例是提前知道名称空间的情况,它突出了const_get可以直接在模块上调用而不是仅在上调用的事实Object


您应该对此添加一个解释。截至目前,它只是一块代码。
乔什·克罗齐耶
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.