クービック Advent Calendar 2015 の 16日目です。
http://qiita.com/kotaroito/items/52ab922f74bee83a9006 の続編(?)となります。
Rails は いかに Bundler を呼び出すか?
端的に言えば、config/boot.rb と config/application.rb を見ればよいです。
config/boot.rb
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
によって、$LOAD_PATHを解決し、
config/application.rb
require File.expand_path('../boot', __FILE__)
Bundler.require(*Rails.groups)
にて、必要な gem を require しています。ちなみに、Rails.groups は RAILS_ENV=productionの時[:default, :production] となります。
なお、この辺の話は Rails Guide の The Rails Initialization Process でも言及されています。
gem version 指定の仕組み
Bundler は 複数 version の gem がインストールされていても、適切に require してくれる素晴らしいツールですが、どんな仕組みか気になりますよね?
コードでは追いかけませんが、sinatra gem を使ってちょっと仕組みを覗いてみます。
まず Gemfile を用意し、bundle install --path=vendor/bundle を実行します。
source 'https://rubygems.org'
gem 'sinatra', '1.4.5'
次に sinatra の version を1つ上げてみます。
source 'https://rubygems.org'
gem 'sinatra', '1.4.6'
bundle install を再実行すると、vendor/bundle は以下のようになります。
$ ll vendor/bundle/ruby/2.1.0/gems/
total 0
drwxr-xr-x 8 kotaroito kotaroito 272 4 7 22:59 .
drwxr-xr-x 9 kotaroito kotaroito 306 4 7 22:49 ..
drwxr-xr-x 13 kotaroito kotaroito 442 4 7 22:49 rack-1.6.0
drwxr-xr-x 8 kotaroito kotaroito 272 4 7 22:49 rack-protection-1.5.3
drwxr-xr-x 23 kotaroito kotaroito 782 4 7 22:49 sinatra-1.4.5
drwxr-xr-x 23 kotaroito kotaroito 782 4 7 22:59 sinatra-1.4.6
drwxr-xr-x 13 kotaroito kotaroito 442 4 7 22:49 tilt-1.4.1
drwxr-xr-x 13 kotaroito kotaroito 442 4 7 22:59 tilt-2.0.1
この状態で bundle exec すると $LOAD_PATH は どうなるでしょうか?
$ bundle exec ruby -e 'puts $LOAD_PATH'
/Users/kotaroito/sandbox/ruby/sinatra/vendor/bundle/ruby/2.1.0/gems/sinatra-1.4.6/lib
/Users/kotaroito/sandbox/ruby/sinatra/vendor/bundle/ruby/2.1.0/gems/tilt-2.0.1/lib
/Users/kotaroito/sandbox/ruby/sinatra/vendor/bundle/ruby/2.1.0/gems/rack-protection-1.5.3/lib
/Users/kotaroito/sandbox/ruby/sinatra/vendor/bundle/ruby/2.1.0/gems/rack-1.6.0/lib
/Users/kotaroito/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/bundler-1.7.3/lib/gems/bundler-1.7.3/lib
/Users/kotaroito/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/bundler-1.7.3/lib
/usr/local/Cellar/rbenv-gem-rehash/1.0.0
...
sinatra-1.4.6 だけが $LOAD_PATH に設定されていることが分かります。
あまり大した話ではありませんが、何かのお役に立てば幸いです。