Rubyで、記号または文字列を取得して同じ名前のクラスに変換する方法はありますか?
たとえば、次のようなクラスがある場合
class Bob
def talk
puts "Hi, I'm bob"
end
end
そして、コードのどこかにあるメソッドにシンボル:bobが渡されますが、何らかの方法でそれをクラスBobに変換できますか?多分何かのような
b = :Bob.new
b.talk
または、これに似た何かをする方法はありますか?
これを行うには多くの方法があります。あなたの文脈の欠如は、「最良の」方法を選ぶことを不可能にします。ここにいくつかの方法があります。
Kernel.const_get(:Bob)
eval(:Bob.to_s)
Kernel.const_get(:bob.to_s.capitalize)
Railsのみ。で使用
文字列を使用する場合:
"Module".constantize #=> Module
"Class".constantize #=> Class
記号付き:
:module.to_s.classify.constantize #=> Module
:open_struct.to_s.classify.constantize #=> OpenStruct
multi-Word記号を扱っている場合は、チェーンに#classify
を追加して、の大文字の使用を適切に処理する必要があります。定数のすべての部分。
http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-constantize
:foo_barをFooBarに変えたい場合、私が見た解決策はどれも機能しません。それがあなたが探しているものなら:
:foo_bar.to_s.split( "_")。collect(&:capitalize).join.constantize
=> FooBar
それが誰かを助けることを願っています。
NameSpace.const_get(classname)
はクラスオブジェクトを返します(classnameにクラスの名前が含まれていると仮定します-クラスではない定数の名前が含まれている場合、その定数の値を返します)。最上位の名前空間はObjectであるため、Object.const_get(:Bob).new
を実行できます。
class Bob
end
def create(name)
return eval("#{name}.new")
end
b = create(:Bob)
puts b.class
モジュール/名前空間のサポートを含む同様のものを探しているときに私が思いついたものは次のとおりです。
['foo', 'bar'].inject {|r,e| "#{r.classify}::#{e.classify}"}.constantize
を生成します
=> Foo::Bar
ただし、これにはRailsが必要であり、もちろん、配列に複数の要素がある場合にのみ機能します。
これはかなり単純に見えるので、私は何かを見逃していると確信しています、なぜこれが良いアプローチではないのか誰かがアドバイスしたいと思いますか?
ありがとう!
私の場合、以下の両方の例が機能しましたが、名前空間を忘れる必要もありません。
Object.const_get("ModuleName::#{class_model_name}")
または
Kernel.const_get("ModuleName::#{class_model_name}").