From: "Ayumu Aizawa" <ayumu.aizawa / gmail.com>
Subject: [ruby-list:45690] Re: クラスメソッド
Date: Thu, 4 Dec 2008 18:20:17 +0900

> 派生した質問なのですが、最初の河村さんの例のようにクラスではなくクラス名の文字列から
> そのクラスのインスタンスを取得することもできるのでしょうか。
> 自分に思いつくのはevalくらいですがもうちょっとスマートな解があれば教えて下さい。

Module#const_getをどうぞ。
ただし、これはネストした定数には対応していないのでイディオムを使います。

class X;  end
module M; end

x_class  = Object.const_get("X") # => X
x_module = Object.const_get("M") # => M
file_stat = "File::Stat".split(/::/).inject(Object){|s,m| s.const_get(m) } # => File::Stat


リファレンスマニュアルより

--- const_get(name, inherit = true) -> object

モジュールに定義されている name で指定される名前の定数の値を
取り出します。

[[m:Module#const_defined?]] と違って [[c:Object]] を特別扱いすることはありません。

@param name 定数名。[[c:String]] か [[c:Symbol]] で指定します。

@param inherit false を指定するとスーパークラスや include したモジュールで
       定義された定数は対象にはなりません。

@raise NameError 定数が定義されていないときに発生します。

  module Bar
    BAR = 1
  end
  class Object
    include Bar
  end
  # Object では include されたモジュールに定義された定数を見付ける
  p Object.const_get(:BAR)   # => 1

  class Baz
    include Bar
  end
  # Object以外でも同様
  p Baz.const_get(:BAR)      # => 1
  # 定義されていない定数
  p Baz.const_get(:NOT_DEFINED) #=> raise NameError
  # 第二引数に false を指定すると自分自身に定義された定数から探す
  p Baz.const_get(:BAR, false) #=> raise NameError

--
rubikitch
Blog: http://d.hatena.ne.jp/rubikitch/
Site: http://www.rubyist.net/~rubikitch/