継承関係のあるクラス間で、子クラスの定義時に、自動的に親クラスに子クラスが登録(メモ)され、それを例えば名前で参照できるようにする。
こんなイメージ。
class Parent; 何らかの処理; end
class Child1 < Parent; NAME='child1'; 何らかの処理; end
Parent['child1']
#=> Child1
これを、メモ用変数と、.inherited
メソッドで実現できた。
module SubclassReferable
# クラスの継承時、親クラスのメモ用変数に、子クラスを登録する。ただし、メモ用変数がある場合のみ。
def inherited klass
@subclass_list.push klass if @subclass_list
end
# 子クラスのNAME定数で、子クラスを見つける。
def [] key
__subclass_list__(__method__).find{ |klass| klass::NAME == key }
end
# メモ用変数がない場合、通常通りNoMethodErrorになる。
def __subclass_list__ method_name
send(:method_missing, method_name) unless @subclass_list
@subclass_list
end
private :__subclass_list__
end
class Parent
# メモ用変数
@subclass_list = Array.new
# `.inherited`等をクラスメソッドにするため、extendする
extend SubclassReferable
end
class Child < Parent
# 参照用のNAME定数を定義する
NAME = 'child'
end
これで、親クラスから.[NAME]
で子クラスを取得できるようになる。
Parent['child']
#=> Child