Rubyでプログラム書くにあたって、bundlerを使わないプログラムは1年ぐらい経つと動かなくなってる事が多々あって、bundlerマジ重要なのと
ぐぐってもあまりbundlerの利点や説明がまとまってる記事がなかったので

研究室のwikiに書いた記事を転載しておく。



Bundlerとは


Bundler: The best way to manage a Ruby application's gems

プロジェクト内で使うRubygemsを管理するしくみ。
プロジェクトの一番上のディレクトリに「Gemfile」というテキストファイルを置き、その中にgemの名前(と必要あればバージョンも)書く。
% bundle install
というコマンドで、gemが一括インストールできる

プログラム内で
require 'bundler'
Bundler.require
と書くと、gemが一括requireできる


どんな時に便利なの?


使用するgemのバージョンを指定できる


開発環境とデプロイ環境で完全に同じバージョンのgemを使えると、無駄なバグが起こらない


gemがメジャーバージョンアップして仕様が変わってしまったので、古いのを使いたい事がある。
railsとかtwitter gemとか、バージョンアップも速いし各バージョンでAPIに互換性がない


あるプロジェクトではtwitter gem 5.x系を、別のプロジェクトでは4.x系を使いたい場合
bundlerなしで
require 'twitter'
するとどちらのプロジェクトでも、バージョンの大きい5.xを読み込んでしまう
そのマシンに存在する最もバージョンの大きいtwitter gemを読み込んでしまうのだ
つまり、新しくtwitter gemを使ったプロジェクトを始めるだけで、古いプロジェクトは何も手を触れていないのに壊れてしまう


作ったプログラムが1年後もちゃんと動くにはbundler必須だとお分かりいただけましたか


rubygems.org以外でホストされているgemをインストールできる

gitリポジトリを指定してインストールできるので、
部外秘なgemは学内に置いておきつつ、Herokuにインストールさせるとかも可能
特定のgit branchやtagを指定してインストールも可能
既存のgemをgithub上でforkして、ちょっとカスタムして使う事もできる
rubygems.orgが死亡してしまった時にも使える


プロジェクトのディレクトリにgemをインストールできる

% bundle install --path (ディレクトリ名)
gemそのものをちょっと修正して使う時や、gemのバグ探しなどに便利


使用方法伝授


準備
まずRubygemsを2.0.0以上にアップデートしておく。
% gem update --system
% gem -v


bundlerをインストール
% gem install bundler
最新版は1.3.4です


Gemfile というテキストファイルを作成し、使用するgemを列挙する
source 'https://rubygems.org'
gem 'sinatra'
gem 'mongoid', '>=2.4.0', '<3.0.0'
gem 'json', '~> 1.7'
gem 'tw', :git => 'git@github.com:shokai/tw.git'
意味 – sinatraはどのバージョンでもいい、mongoidは2.4以上3未満、jsonは1.7.x系の最新、twはgithubから開発版をインストール

このファイルはbundle initすれば雛形を生成してくれるので、書式忘れたらinit。


gemをインストール

% bundle install


Gemfile.lockが無い場合(はじめてbundle installした時)
Gemfile.lockというファイルが生成される
gemの名前とバージョンが列挙されている
これをgitにcommitしておくと吉
Gemfileではゆるめにバージョン指定して、詳細はGemfile.lockに任せた方がいい


gemのインストール元
ローカルにないgemはrubygemsから最新版が
ローカルにあるgemは、ローカルにある中で一番バージョン番号が大きいものがインストールされる


Gemfile.lockがある場合(2回目以降のbundle install時)
書いてあるバージョンのgemがインストールされる


gemのアップデート

% bundle update
rubygems.orgから最新版を取得し、Gemfile.lockを更新する



bundlerで指定したgemを使う

これやらないと、システムに入っている最新版gemを使ってしまいます


bundlerで指定したgemを使う(実行時に指定)
今まで
% ruby foo.rb
% rackup config.ru
等で実行していたのを、
% bundle exec ruby foo.rb
% bundle exec rackup config.ru
とする


bundlerで指定したgemを使う(プログラム内で指定)
require 'bundler/setup'
これを書けば使用バージョンがGemfile.lockに書かれている物に固定される(俺はこっち派)

個別にrequireしてもいいし、
Bundler.require
でgemを一括requireしてもいい。


Gemfileはカレントディレクトリにある物を参照するので、crontabで使う場合はプロジェクトの中にcdしてからrubyしないといけません。
7時30分に実行する例
30 7 * * * cd $HOME/src/ruby/myapp && bundle exec ruby start.rb > /dev/null 2>&1


gemのテンプレも作れる


% bundle gem 名前
でgemの雛形が作れる。
作ったgemは特に審査などなくrubygems.orgにホストしてもらえて、世界中に大公開されてみんなに使ってもらえるのでどんどん作るといいと思います



まとめ


そんな感じで、Rubygemsたちの更新は速いのでGemfileをちゃんと書かないとすぐにプログラムは動かなくなります。
Bundlerを使いましょう