今回はRuby on Railsについてメモ。

autoloadで自動読み込みされないファイル1をcontrollerの中などでrequireを使って読み込んだ場合、そのファイルはdevelopmentモード時でもユーザアクセス毎に再読み込みされません。そのため、ファイルを編集してもwebサーバを再起動しないと変更が反映されないので、デバッグがやりづらくて困ってました。

解決策がないかと思って、ググってみたところ、以下のページに解決策が書いてありました。
http://www.pistolfly.jp/weblog/2007/06/require-dependency.html

requireじゃなくて、require_dependencyでファイル読み込みすれば良いということでした。
require_dependencyの挙動については、上のリンク先を参照してください。
この辺り(autoload周辺)って、Ruby on Rails公式なドキュメントが見当たらないですねえ。・・・実装を読めってことか。

以下、問題のコード例と解決方法。(ruby 1.8.5, rails 2.3.3, WEBrick 1.3.1で実験しました。)

ファイル読み込みの対象となるファイルを用意します。

<rails_project>/lib/hoge_fuga.rb

RUBY:
  1. class Hoge
  2.   def hoge
  3.     return "abc"
  4.   end
  5. end

上のファイルを読み込むcontrollerを用意します。
このとき、requireの代わりにrequire_dependencyでファイルを読み込みます。

<rails_project>/app/controllers/test_controller.rb

RUBY:
  1. #require 'hoge_fuga'
  2. require_dependency 'hoge_fuga'
  3.  
  4. class TestController <ApplicationController
  5.   def hoge
  6.     a = Hoge.new
  7.     render(:text => a.hoge)
  8.   end
  9. end

んで、Webサーバを起動。

$ cd <rails_project>
$ ruby script/server

で、ブラウザからtest/hogeにアクセスすると、ブラウザ上にabcが出力されます。
この状況で、<rails_project>/lib/hoge_fuga.rbを以下のように書き換えてみます。

RUBY:
  1. class Hoge
  2.   def hoge
  3.     return "123"
  4.   end
  5. end

変更を保存した後、ブラウザからtest/hogeにアクセスすると、ブラウザ上に123が出力されます。
確かに、Webサーバを再起動しなくても、<rails_project>/lib/hoge_fuga.rbが再読み込みされてますね。

これでデバッグがしやすくなるなあ。

  1. Railsの場合、クラス定義と定義が記述されたファイルの名前が対応づいてないとautoloadで自動読み込みされません(たぶん)。例えば、FooBarというクラスの定義はfoo_bar.rbというファイルの中で行われてないとautoloadにされません。 []