Satoryu's Diary

Rubyが好きなプログラマーの日記。日々の生活、開発に関するメモとか考えとか。


2013年08月11日 [長年日記]

_ gemでインストールしたコマンドをバージョン指定して起動する方法

例えば、Rails なんかだと

$ gem list rails 

*** LOCAL GEMS ***

rails (4.0.0, 3.2.14, 3.2.10, 3.2.8)

といったように、複数のバージョンがインストールされている時に、最新ではなく3.2系の開発をしたい場合がある。 そういったときは、

$ rails _3.2.14_ new rails_app

とすることで、railsコマンドを提供するrails gemのバージョンを指定することができる。

どういう仕組みか?

Rubygemとしてインストールされたコマンド*1は、Rubygemがbinstubを作り、それが起動する仕組みになっている。 例えば、bundler なんかの場合、bundlerが提供するbundleコマンドのパスは、

$ which bundler
/path/to/home/.rvm/gems/ruby-1.9.3-p429@global/bin/bundle

を見ておりように、インストールされたgemが展開されている~/.rvm/gems/ruby-1.9.3-p429@global/gems/bundler-1.3.5/を参照していない。このbundleコマンドが、binstubになっている。その中身が、こんな感じ。

 # !/usr/bin/env ruby_noexec_wrapper
 # 
 # This file was generated by RubyGems.
 # 
 # The application 'bundler' is installed as part of a gem, and
 # this file is here to facilitate running it.
 # 
 
require 'rubygems'
 
version = ">= 0"
 
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
  version = $1
  ARGV.shift
end
 
gem 'bundler', version
load Gem.bin_path('bundler', 'bundle', version)

これは他のコマンドも同様の記述になっている。

Tags: rubygems ruby

*1 binディレクトリ以下の実行権限のあるファイル


最近の投稿

翻訳しました(ちょっとだけ)

follow us in feedly