bundlerのgemをrubyスクリプト実行時にロードする方法

bundler、言わずと知れたrubyのgem管理用パッケージ。

railsプロジェクトを作るにも、bundlerでローカルインストールしてプロジェクトごとにバージョン管理する、という使い方が多いと思います。
そのような場合は"bundle exec rails"の形でアプリケーションを実行すれば後は良きに計らってくれるわけですが、
ruby単体のスクリプトを実行する場合は「bundlerでインストールしたgem」ってどうすれば使えるんでしょうか。

と思ったので、調べたことをメモしておきます。


検証環境

  • Mac OS X
  • ruby 2.1.2(rbenvのlocalで指定)
  • bundlerのインストールパスはvendor/bundle

準備

とりあえずbundler環境を初期作成します。

$rbenv local 2.1.2
$ rbenv exec bundle init
Writing new Gemfile to /Users/hogehoge/Documents/Gemfile

何でもいいのでとりあえずnokogiriだけインストール。

#Gemfile
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
gem 'nokogiri'
$ rbenv exec bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/..............
Fetching version metadata from https://rubygems.org/..
Installing mini_portile2 2.0.0
Installing nokogiri 1.6.7.2 with native extensions
Using bundler 1.10.6
Bundle complete! 1 Gemfile dependency, 3 gems now installed.
Bundled gems are installed into ./vendor/bundle.

これでrbenvのローカル環境下にbundlerによるgemパッケージのインストールができました。


とりあえずロードパスを確認

普通に考えると、ruby実行時のロードパスにbundlerのインストールパスが通っていればいいはず。

rubyのロードパスはグローバル変数"$:"に格納されます。

$ irb
irb(main):001:0> puts $:
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0/x86_64-darwin14.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/site_ruby
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0/x86_64-darwin14.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/2.1.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin14.0
=> nil

見事にないですね。


試しに先ほど入れたnokogiriをrequireしてみると

irb(main):001:0> require 'nokogiri'
LoadError: cannot load such file -- nokogiri
	from /Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from (irb):1
	from /Users/hogehoge/.rbenv/versions/2.1.2/bin/irb:11:in `<main>'

当然エラーとなります。


bundlerのパスを追加する

では、先ほどbundlerのインストールパスとして指定したvendor/bundleはどうやってロードパスに追加すれば良いのでしょうか。
それはとても簡単です。

Bundler.requireを実行する

gemのrequire前に以下のコードを追加します。

require 'bundler'
Bundler.require

Bundler.requireにより、Gemfile内に記載されている全てのgemを検索してロードパスへ追加します。

irb(main):003:0> require 'bundler'
=> true
irb(main):004:0> Bundler.require
=> [<Bundler::Dependency type=:runtime name="nokogiri" requirements=">= 0">]
irb(main):005:0> puts $:
/Users/hogehoge/Documents/vendor/bundle/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib
/Users/hogehoge/Documents/vendor/bundle/ruby/2.1.0/extensions/x86_64-darwin-14/2.1.0-static/nokogiri-1.6.7.2
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/bundler-1.10.6/lib/gems/bundler-1.10.6/lib
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/bundler-1.10.6/lib
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0/x86_64-darwin14.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/site_ruby
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0/x86_64-darwin14.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/2.1.0
/Users/hogehoge/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin14.0
=> nil
irb(main):006:0> require 'nokogiri'
=> true

先頭にnokogiriのパスが追加され、当然requireもできています。



非常に簡単なことなのですが、普段意識していないためいざという時に戸惑ってしまいますね。

参考とさせていただきました。
http://shokai.org/blog/archives/7262
Bundler.setup vs. Bundler.require

たのしいRuby 第5版

たのしいRuby 第5版

Ruby on Rails 5.0 インストール手順書 (OIAX BOOKS)

Ruby on Rails 5.0 インストール手順書 (OIAX BOOKS)