Rubyの文字列名からクラスインスタンスを作成するにはどうすればよいですか?


121

クラスの名前があり、そのクラスのインスタンスを作成して、そのクラスのスキーマに存在する各rails属性をループできるようにしたいと思います。

どうすればいいですか?

  1. チェックしたいクラスの文字列として名前を持っています
  2. 私ができるようにクラスインスタンスをインスタンス化する必要があると思います
  3. その属性をループして印刷します。

1
これは素晴らしい質問です。それを尋ねると、使用してから私を節約してくれてありがとうeval
デビッド・ウェストを

回答:


219

レールでは次のことができます:

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、2011年

@ウェスさん、これは役に立ちました。ありがとう!簡単な質問-これはネストされたモジュールでも機能しますか?たとえば、clazz = 'Foo::Bar::Uber'
iaacp

@iaacpはい、ネストしたレベルの数だけ機能します。
2015年


6

これを試して:

Kernel.const_get("MyClass").new

次に、オブジェクトのインスタンス変数をループします。

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

ありがとう、私は実際にアクティブレコードモデルの列をループする必要があるので、これは私にとっては機能しませんが、「純粋な」Rubyアプリでは役立ちます:)
mhenrixon

1
ActiveRecord#attributes()および/またはActiveRecord#attribute_names()を確認してください。
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


これに説明を追加する必要があります。現在のところ、これはコードのブロックにすぎません。
Josh Crozier
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.