Ruby で Java のリフレクション的なことをしたくなった。リフレクションがどういうものかは置いとくとして,要するに,
Class clazz = Class.forName("Sample"); Method method = clazz.getMethod("sample"); method.invoke(clazz.newInstance());
ということをやりたい。何に使うかは聞かないで欲しい。Ruby も最近やり始めたので最適解なのかどうかはわからないが,
Dir[File.expand_path('./temp') << '/*.rb'].each do |file| require file end
として自分のいるところの temp
フォルダ配下に *.rb
のファイルがあれば全部 require
するようにしてみた。その後,
dir = "./temp" @class_name_list = Array.new Dir::glob(dir << "/*.rb").each { |entry| file_name = File::basename(entry) class_name = file_name[0, file_name.length - 3].capitalize @class_name_list.push(class_name) }
という感じ。./temp/*.rb
を走査して取得したパスを File::basename
でファイル名だけ取り出す。それの拡張子を取りつつ,先頭の文字を*1大文字に変更。できあがったクラス名を配列へ格納する。
これで実行したいクラス名は require
されて全部配列に持つことができたので,いざ実行。
temp = Object.const_get(clazz).new
とすればクラス名の文字列からクラスをインスタンス化することができる。Ruby は Java みたいに面倒じゃない*2ので,このあと temp
オブジェクトから自由にメソッドが呼べる。Interface とかはなくてよい*3。
以上。