Padrinoが生成するconfig/boot.rbは末尾で Padrino.load! を呼び出していますが、実はその中でbefore_loadとafter_loadを呼んでいます。Padino.load!の定義は、ソースコードを調べると次のようになってます。
def load! return false if loaded? began_at = Time.now @_called_from = first_caller set_encoding set_load_paths(*load_paths) Logger.setup! require_dependencies("#{root}/config/database.rb") Reloader.lock! before_load.each(&:call) require_dependencies(*dependency_paths) after_load.each(&:call) logger.devel "Loaded Padrino in #{Time.now - began_at} seconds" Thread.current[:padrino_loaded] = true end
つまりbefore_loadとafter_loadの違いは、Padrinoの各種依存ファイルのrequireの前か後か、という違いです。
上記Padino.load!をよく見てみると、Loggerだけ扱いが別になっています。Logger関連の設定はbefore_loadやafter_loadの中に書いてもそれだけでは有効になりません。config/boot.rbのトップレベルかつPadrino.load! の前に記述するか、手動でLogger.setup!を呼ぶ必要があります。
で、ようやく本題ですが、上記のPadrino.load!を見ながら、実際フレームワーク全体がどう読み込まれるのか調べてみたくなりました。Loggerのログレベルをdevelに設定すると、起動時にロードしたファイルをログに出してくれるようになるので、ロードの順番がわかります。まとめるとPadrinoのロードの主要手順はだいたいこんな感じになっているようです。
- Loggerの設定
- config/database.rbのロード
- before_loadフックの実行
- lib/の中にあるファイルのロード
- models/の中にあるファイルのロード
- (shared/lib/の中にあるファイルのロード)※デフォルトでは存在しない
- (shared/models/の中にあるファイルのロード)※デフォルトでは存在しない
- config/apps.rbのロード
- app/app.rbのロード
- アプリケーション名::Appのインスタンス生成
- after_loadフックの実行
- app/controllers/の中にあるファイルのロード
- app/helpers/の中にあるファイルのロード
なるほど。ちなみに意外だったのは、controllersとhelpersのロード順が予想と逆だったこと。でもどうせメソッド定義なので特にロード順に影響はないはずです。
ロードの順番に影響を受けるようなコードの書き方をすることは少ない(というかなるべく避けるべき)と思いますが、デバッグの役に立つこともありますので一応知っておくとよいと思われます。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。
0 件のコメント:
コメントを投稿