ubygems
rubygems を使ってライブラリをインストールすると、そのまま require 'sqlite3' のようにすれば使えるようになる。
ところが、ライブラリパスである $LOAD_PATH を見てみると、その中に lib/ruby/gems/1.8/gems 以下のフォルダは含まれていなかった。
irb(main):001:0> $LOAD_PATH => ["c:/ruby/lib/ruby/site_ruby/1.8", "c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt", "c:/ruby/lib/ruby/site_ruby", "c:/ruby/lib/ruby/1.8", "c:/ruby/lib/ruby/1.8/i386-mswin32", "."]
不思議だったのでいろいろと情報をあたってみた。
犯人は RUBYOPT
環境変数を見てみると RUBYOPT に -rubygems が設定されていた。ruby を起動するごとに RUBYOPT が自動的にコマンドライン引数に付加されるらしい。どうやら、One-Click Ruby のセットアップ時に、環境変数 RUBYOPT に -rubygems が設定されていたようだ。
試しに RUBYOPT を空にして require 'sqlite3' するとエラーになった。
次に、-rubygems オプションの仕組みが気になった。ruby 本体に rubygems 用の特殊な処理が組み込まれているとは考えづらい。
-r オプション
ruby --help を実行すると、-r はライブラリを読み込むためのオプションだと分かった。
例えば、MD5 モジュールを使うとき、-r を使わなければ次のようになる。
ruby -e "require 'md5'; p MD5::md5('a')"
これを、-r を使って書き換えると
ruby -r md5 -e "p MD5::md5('a')"
とできる。
-r のあとのスペースは省略できるので
ruby -rmd5 -e "p MD5::md5('a')"
としてもよい。
-rubygems の答え
そこで、-rubygems。
なんと、lib/ruby/site_ruby/1.8 に ubygems.rb というファイルが用意されていた。ubygems.rb は require 'rubygems' してるだけ。
この ubygems.rb があるおかげで
ruby -r rubygems foo.rb
の変わりに
ruby -rubygems foo.rb
と書けるわけだ。-rubygems は -r ubygems と解釈される!
ubygems.rb が rubygems.rb を require する。
なるほどねー。
rubygems は何をやってるか
最後に、rubygems が中で何をやってるかを軽く見てみた。
rubygems.rb から呼ばれる rubygems/custom_require.rb では Kernel#require の処理を置き換えている。
module Kernel alias gem_original_require require # :nodoc: # コメントいっぱい def require(path) # :nodoc: gem_original_require path rescue LoadError => load_error # 例外処理いっぱい end end # module Kernel
ということで、require 'rubygems' するか -rubygems オプションを指定すると、require がラップされるようだ。
lib/ruby/gems/1.8/gems の下の適切なバージョンのライブラリを読み込んでくれるわけですな。