人気ブログランキング | 話題のタグを見る

RoR script/server

config/boot.rb の解読が目的なのに、横道にまたそれてしまうが、RoRでアプリケーションを作った後最後に呼び出すscript/server について見てみたい。

rails foo でアプリケーションの骨組みを作り、script/generate scaffold bar でたたき台のMVCを作成し、最後に script/server でアプリケーションを開始するのが RoR による開発の開始になる。そのとき、複雑な設定をこなして、サーバーを立ち上げるまでの一連の処理をこなすのが script/server の仕事だが、その中身を見てみると、なんとたった3行なのだ。

~/rails/demo$ cat script/server
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/server'

config/boot.rb と command/server.rb という二つのファイルを require しているにすぎない。

require はライブラリを読み込むときの命令なので、二つのファイルを呼び出しただけで、プログラムが動き出すのは不思議に思われるが、boot.rb のソースは、Rails モジュールの定義を行った後に、Rails.boot! というトップレベルで実行される命令文が書いてある。これが require されたあとに実行されるので、command/server は動き出すのだ。

require で呼び出されるファイルにトップレベルで動作する命令文まで記述してあると、呼び出す側での操作がいらなくなる。boot.rb の側のスクリプトの変更があっても、script/server 側はまったくいじる必要がない。それが、script/server の require 文だけの不思議な記述の理由だ。

また、RAILS_ROOT の取得と、Rails モジュールの定義と、Rails.boot! の3つだけの記述という boot.rb の奇妙な構成の理由もこの観点から考えるとよく分かる。ブート時の動作を、Rails モジュールにカプセル化することによって、一連の動作を部品として扱えるようにしているのだ。このため、トップレベルの名前空間は、RAILS_ROOT と Rails モジュールしか使わない。呼び出す側も単に boot.rb を require するだけということになる。

さらに、class << self で作られた、Rails モジュールのクラスメソッドの意義も分かる。本来ならトップレベルで実行される命令文をここに置いたのだ。また、class << self 〜 end で囲むことができるため、それらの命令文を一まとめにしかも簡潔に表示することができる。

もちろんローカル変数のスコープの関係で、require されるファイルの局所変数は呼出側のトップレベルの名前空間を消費しない。しかし、明示的にモジュール化されていると、安心感があるのは事実だ。

いずれにせよ、boot.rb はあの簡潔なコードで、Rails アプリケーションの複雑な設定を一手に引き受けているわけだ。
by tnomura9 | 2008-10-18 03:14 | Ruby | Comments(0)
<< RoR config/boot... 代入文を関数にする理由 >>