Railsのautoloadの使い方に気をつけよう

Railsには便利なautoloadがあるので、たとえば lib/util/test.rb に

module Util
  module Test
    def hoge
      puts 'hello'
    end
  end
end

と書いて、コントローラなどで

def HogeController < ApplicationController
  def index
    Util::Test::hoge
  end
end

とやれば、勝手にロードしてくれます。

しかし、毎回打つのが面倒だからと

def HogeController < ApplicationController
  include Util
  def index
    Test::hoge
  end
end

みたいなことをやろうとしても、うまくいきません。

railsのソースコード内で、以下のような場所にあるdependencies.rbがautoloadを実現しているのですが、

C:\ruby\lib\ruby\gems\1.8\gems\activesupport-2.3.5\lib\active_support\dependencies.rb

これは、const_missingが発生したときに、定数名から該当する.rbファイルを自動的に読むものです。

つまり、include Util とやると、lib/util.rb を探しに行ってしまいます。
utilはフォルダであってファイルではないので、見つからずエラーになります。

毎回 Util::Test::hoge とやるか、

def HogeController < ApplicationController
  include Util::Test
  def index
    hoge
  end
end

のようにやれば済む話なのですが、Test::hogeという呼び方をしたくなりますよね・・・

Testをclassにして、hogeをクラスメソッドにして、手動でloadすれば解決しますが、いまいち美しくないです。

そもそもnamespace的に使おうとするのが間違いなのかもしれませんが・・・
もっと良い方法を考えてみます。

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

baba

ゆとりプログラマー。

高校時代から趣味でプログラミングを初め、そのままコードを書き続けて現在に至る。慶應義塾大学環境情報学部(SFC)卒業。BPS設立初期に在学中から参加している最古参メンバーの一人。Ruby on Rails、PHP、Androidアプリ、Windows/Macアプリ、超縦書の開発などを気まぐれにやる。軽度の資格マニアで、情報処理技術者試験(15区分 + 情報処理安全確保支援士試験)、技術士(情報工学部門)、CITP、Ruby Programmer Goldなどを保有。

babaの書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ