Ruby/クラス/動的にクラスを作る

Ruby/クラス/動的にクラスを作る

クラスを生成する

通常のクラスを作る構文は

class Hoge
  def piyo
    p "piyopiyo"
  end
end

RubyのクラスはClassクラスのインスタンスなので↑はClassオブジェクトリテラルということになる。 リテラル表記があるなら通常の表記もある

Hoge = Class.new do
  def self.piyo
    p "piyopiyo"
  end
end
 
Hoge.piyo #=> piyopiyo

このように働く。 なんかJavascriptチック。

もしかしたらこっちのほうがRubyの性質を的確に現している構文かも。

まぁ使わないと思うけど

Hoge = Class.new do |fuga|
  def fuga.piyo
    p "piyopiyo"
  end
end

という風に表記して生成された原始のself(クラスインスタンス自身)をfugaという変数で受けることもできる。

ここでクラスメソッドはClassクラスインスタンスの特異メソッドという実装になっていることがわかる。

これが無名クラスとわかれば

A = Hoge
A.piyo #=>piyopiyo

というハンドリングができることも当然だと感じられる。

動的に継承

クラスを動的に生成しつつ、継承元も動的に変えたい場合は、コンストラクタにクラス自体を渡すと継承される

class Hoge
  def piyo
    p "piyopiyo"
  end
end
 
Fuga = Class.new(Hoge)
 
fuga = Fuga.new
fuga.piyo #=> piyopiyo

こんな具合だ。 あとはRubyはオープンクラスなので自由自在にやってくれ

ここまでくると

Hoge = Class.new(Class.new do
  def self.piyo
    p "piyopiyo"
  end
end)
 
Hoge.piyo

こういう書き方が成り立つのもわかるだろう

クラス名を動的に

クラスとはClassオブジェクトが詰まった定数と考えていい。 なので定数の動的割り当てを使えばクラス名を動的に変化させることができる

Hoge = Class.new do
  def piyo
    p "piyopiyo"
  end
end
 
hoge = Hoge.new
hoge.piyo #=> piyopiyo
 
Object.const_set("Fuga", Hoge)
fuga = Object.const_get("Fuga").new
fuga.piyo #=> piyopiyo

Object.const_setメソッドを使いHogeクラスオブジェクトをFugaという名前で動的に名付ける。 これは文字列だから自由自在

そして呼び出すときはObject.const_getで名付けたオブジェクとで呼び出せばOK

バージョン

  • 2010-10-26 クラス名動的変更
  • 2009-04-03 新規 Ruby 1.8.6

タグ

ruby/class/dynamic_class_build.txt · 最終更新: 2014-09-17 11:29 by ore