大変厳しい監視にも負けず、普通にRubyの話をします。
文字列のクラス名をクラスにするには、Rubyの場合evalとかもあるけれど(参照: Class.forNameはどう書くのか、コメントも)、 Object.const_get を使うのが一番安全な気がします。変なコードをねじ込まれてもNameErrorになるだけですし。
irb(main):001:0> Object.const_get("String") #=> String irb(main):002:0> Object.const_get("String").new #=> ""
でもこれ、たとえば Net::HTTP みたいな名前空間付きのクラスを呼ぶとエラーになりますんよ。
irb(main):001:0> require 'net/http' => true irb(main):002:0> Object.const_get("Net::HTTP") NameError: wrong constant name Net::HTTP from (irb):2:in `const_get' from (irb):2
なので、以下のようなメソッドをつくりました。
nested_const_get.rb
1 2 3 4 5 6 7 8 9 10 | class Object def self.nested_const_get(*args) stack = (args[0] =~ /::/) ? args[0].split("::") : args klass = Object while const = stack.shift klass = klass.const_get(const) end klass end end |
irb(main):001:0> require 'nested_const_get' #=> true irb(main):002:0> Object.nested_const_get("String") #=> String irb(main):003:0> require 'net/http' #=> true irb(main):004:0> Object.nested_const_get("Net::HTTP") #=> Net::HTTP irb(main):005:0> Object.nested_const_get("Net::HTTP").start("blog.udzura.jp", 80) #=> #<Net::HTTP blog.udzura.jp:80 open=true> irb(main):006:0> Object.nested_const_get("Net::HTTP::Get") #=> Net::HTTP::Get irb(main):007:0> Object.nested_const_get("Net::HTTP::Get::METHOD") #=> "GET"
ハックというほどでもないですね。一応、何かの役に立つこともあろうかと。

