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
複数単語のシンボルを扱っている場合は#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.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が必要であり、もちろん、配列に複数の要素がある場合にのみ機能します。
これはかなり単純に思えるので、何かが欠けていると確信しています。なぜこれが良いアプローチではないのか、誰かアドバイスしてくれませんか?
ありがとう!