【Ruby】メタプログラミングで動的にクラスとメソッドを定義する
やりたいこと
- メタプロで、動的にクラスとそのメソッドを定義したい。
- Api関係の部分使いたいので、Moduleの配下に定義したい。
- 動的に定義したクラスは他のクラスを継承した形にしたい。
方法
- const_setを使っていく
- define_methodを使っていく
結果
これでいける!勝つる!
module Hello class_list = ['Ohayo','Konnichiwa','Konbanwa'] #親クラスHelloの動的定義 const_set(:'Hello', Class.new do def hello puts 'hello.' end end) #親クラスを継承した子クラスOhayo, Konnichiwa, Konbanwaの動的定義 #動的にメソッドも定義する class_list.each do |v| const_set(v.intern, Class.new(Hello) do define_method v.downcase do puts v + ' desu.' end end) end end #実際に使ってみる。 #Ohayoクラスの生成 hello = Hello::Ohayo.new #親クラスのメソッド呼び出し hello.hello # -> hello. #子クラスの動的に定義したメソッドの呼び出し hello.ohayo # -> Ohayo desu.
ポイント:Classクラスのnewメソッドを理解する
公式リファレンスマニュアルに以下の記載があります。
class Class (Ruby 2.7.0 リファレンスマニュアル)
new(superclass = Object) -> Class
new(superclass = Object) {|klass| ... } -> Class
どういうことか。
1行目については引数に継承したいクラスオブジェクトを入れると、継承してくれる。デフォルトはObjectクラスの子クラスとしてclassが定義される。
2行目についてはブロックを与えるとその中身はclassに紐づく。つまりブロック内にメソッドを直書きすれば良い。
この2点を理解すると、↑のコードは問題なく読めると思います。
あとは適当に外部から取得してきた風に配列の中にクラス名を格納して、順次クラス定義をしているのと、define_methodで動的にメソッド定義してみました。
誰かのお役に立てれば幸い。
今回は以上です。
- 作者:Paolo Perrotta
- 発売日: 2015/10/10
- メディア: 大型本