Rubyのautoloadは廃止されるかもしれないので、代わりの方法を用意しておきたい。
Rubyにはconst_missingというヤバいメソッドがある。このメソッドは未定義の定数にアクセスした時、NameErrorが発生する前に処理をフックする事ができる。superを呼べばそのままNameErrorがraiseされ、値を返せば、それが未定義定数の値として使用されるのだ。Rubyにはこういう悪魔のような邪悪なメソッドがしれっと用意されているので恐ろしい…
このconst_missingの中で必要なファイルをrequireし、const_getで取得できなかった定数を取得して返せばautoloadの代わりになりそうだ。
# autoloader.rb require "set" module AutoLoader def auto_require hash @autoloading = hash end def const_missing const @missing_const ||= Set.new if @missing_const.include? const super end @missing_const.add const file = @autoloading[const] if file.nil? super end require file const_get(const) end end
const_getで定数が取得できないとまたconst_missingが呼ばれ無限再帰してしまうので、その対策も忘れずに。
自動ロードされるhoge.rbにはTest::Hogeクラスの定義を書いておく
# hoge.rb class Test::Hoge def to_s "test_hoge" end end
自動ロードする側はextendして機能をクラスに取り込む。
# main.rb require "./autoloader" class Test extend AutoLoader auto_require :Hoge => "./hoge.rb", :Fuga => "./fuga.rb" def get_hoge Hoge.new end end puts Test.new.get_hoge
これを実行してみると…
$ ruby main.rb test_hoge
できた。
これが必要になる日は来るのでしょうか?