rails new としたとき何がおこるのか調べようとしてあきらめた
まず rails コマンドがどこにあるのか調べよう
$ which rails
/home/plonk/.rvm/gems/ruby-2.1.2/bin/rails
ただの Ruby スクリプトだ。
$ file `which rails`
/home/plonk/.rvm/gems/ruby-2.1.2/bin/rails: Ruby script, ASCII text executable
rails:
最初の行はスクリプトを実行するインタプリタを指定するもので
/usr/bin/env
を使うことでインタプリタのパスを直接指定せずに環境変数によっ
て切り替えるようになっている。
コメントによれば、RubyGems によって生成されたファイルで railties ってい うアプリが関係しているらしい。
第一引数で _VERSION_
の形で railties のバージョンが指定してあれば、それを “>= 0” の代わりに指定して gem 'railties', version
を呼び出すというコード。
gem はなにをしているかというと、指定のバージョンの railties が読み込ま
れるように $LOAD_PATH
を設定するらしい。
http://docs.ruby-lang.org/ja/2.0.0/method/Kernel/i/gem.html
Gem.bin_path
の部分は rails コマンドの実行パスを railties ジェムに求め
ている様子。
http://apidock.com/ruby/Gem/bin_path/class
実際に実行するとこういうパスが出てくる。
> Gem.bin_path('railties', 'rails')
=> "/home/plonk/.rvm/gems/ruby-2.1.2/gems/railties-4.1.7/bin/rails"
railties っていうのは何かと言うと…
$ gem list railties --details
*** LOCAL GEMS ***
railties (4.1.7)
Author: David Heinemeier Hansson
Homepage: http://www.rubyonrails.org
License: MIT
Installed at: /home/plonk/.rvm/gems/ruby-2.1.2
Tools for creating, working with, and running Rails applications.
なるほど、Rails のコマンド類は railties っていうサブパッケージに含まれ ているということかな? (railties は Rails と何のかばん語だろう?)
…ともかく rails コマンドの実際の(?)パスが出てきた。見てみよう。
スクリプトのある場所を基準にして3つ上のディレクトリにある .git ディレク トリを求めている。
plonk@xubuntu-14:~/.rvm/gems/ruby-2.1.2/gems/railties-4.1.7/bin$ ls ../../../.git
ls: ../../../.git にアクセスできません: そのようなファイルやディレクトリはありません
Whoops、存在しない。ともかく、存在すれば ../../lib
を $:
の先頭に追加するということのようだ。
$:
と $LOAD_PATH
と同じ。覚えられないから何度でも確認する。
> $LOAD_PATH == $:
=> true
> $LOAD_PATH.object_id == $:.object_id
=> true
ここまでのところ、自分の環境には関係のないことをしているようだ。そして rails/cli が require されている。cli っていうのは Command Line Interface だろう(どや顔)。
ここにあった。
cli.rb:
AppRailsLoader
クラスを一行目でロードしているようだ。コメントによれば
Rails アプリケーション内から呼び出されたのならば exec するのでこれ以降
は実行されないとある。
exec というのは現在のプロセスを置き換えるシステムコールだから、意味が通 る。http://api.rubyonrails.org/classes/Rails/AppRailsLoader.html
よくわからないが、./bin/rails
か ./script/rails
があればそれを実行する
ということなのだろう。…はっ、ということは rails と打つとき、そのプロジェ
クトの bin ディレクトリにある rails コマンドが実行されていたわけか!
…でも、rails new するときは、これらのファイルはまだ存在しないから
exec_app_rails
はフォールスルーするはずだ。
rails/ruby_version_check
のロードは本質的でなさそうなので、無視する。
次の行は、Ctrl+C が押されて SIGINT が発生したら改行を表示して(きっとエ
ラーメッセージとプロンプトがくっつかないようにするためだろう)終了するよ
うに設定している。
コマンドライン引数の最初の項目(サブコマンド)が plugin だったら読み捨て て rails/commands/plugin をロードし、それ以外だったら rails/commands/application をロードする。rails new の場合を考えているか ら実行するのは else 節の方のパスのはずだ。
というわけで application.rb に行く。
内容。
基本的には AppGenerator クラスをロードして start クラスメソッドにコマン ドライン引数を渡しているようだ。こいつが主な仕事をしているんだろう。
というわけで、 app_generator.rb
と AppGenerator
のスーパークラスが
ある app_base.rb
を見にいった。だがさっぱりわからないぜ、というわけで
あきらめた。