CUBE SUGAR CONTAINER

技術系のこと書きます。

Mac: Ruby の開発環境を整えてみる

諸事情により Ruby を書くことになるかもしれないので、環境を整えるためにやったことをメモしておく。 rbenv を使って複数バージョンの Ruby をインストールして、Bundler で vendoring できるようにするところまで。

今回使った環境は次の通り。

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G1108

Homebrew をインストールする

まずは rbenv をインストールするために Homebrew をインストールしておく。 Homebrew はコマンドラインで色々なツールをインストールするためのソフトウェア。

$ xcode-select --install
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

rbenv をインストールする

rbenv を使うことで任意のバージョンの Ruby をインストールできる。

まずは Homebrew の状態を最新にしておく。

$ brew update && brew doctor && brew upgrade

その上で rbenv をインストールする。

$ brew install rbenv

rbenv をセットアップする

まずは rbenv init を実行するものらしいので、やってみる。

$ rbenv init
# Load rbenv automatically by appending
# the following to ~/.zshrc:

eval "$(rbenv init -)"

なるほど、上記を行を使っているシェルの設定ファイルに追加せよということね。

ただ、今の環境は Oh-my-zsh を使っている関係で .zlogin に個人的な設定を入れているので、そちらを使うことにしよう。

どうせなら、上記をそのままシェルの設定ファイルにリダイレクトしてもよさそう。

$ rbenv init >> ~/.zlogin

ただ、設定ファイルは rbenv を入れていない環境でも使いまわしているので、次のようにした。 rbenv コマンドの有無を確かめた上で rbenv init を実行する。

$ cat << 'EOF' >> ~/.zlogin
# rbenv
which rbenv  > /dev/null 2 > /dev/null
if [ $? -eq 0 ]; then
  eval "$(rbenv init -)"
fi
EOF

書き終わったら、シェルの設定ファイルを読み込み直すのをお忘れなく。 これで rbenv をインストールしたディレクトリにパスが通る。

$ source ~/.zlogin

rbenv を使ってみる

まずは、インストールできる Ruby のバージョンを確認してみる。

$ rbenv install -l

どうやら、今 (2016/11 現在) インストールできる最新のものは 2.3.1 らしい。

$ rbenv install 2.3.1

新しいバージョンをインストールしたときは rbenv rehash コマンドを実行する。

$ rbenv rehash

使うバージョンを切り替える

今は macOS がデフォルトでインストールしているバージョンを使っている状態になっている。

$ ruby --version
ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin15]

普段使いのバージョンを切り替える

これを、先ほど rbenv でインストールしたバージョンに切り替えるには rbenv global サブコマンドを使う。

$ rbenv global 2.3.1

これで、普段使いのバージョンが切り替わった。

$ ruby --version
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

元に戻したいときは rbenv global system とすれば、元々システムが使っていた処理系に切り替わる。

$ rbenv global system
$ ruby --version
ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin15]

特定のプロジェクトで使うバージョンを切り替える

特定のディレクトリ (プロジェクト) で使うバージョンを指定したいなら rbenv local を指定する。

$ rbenv local 2.3.1

すると、そのディレクトリに .ruby-version という使うバージョンを指定するファイルができる。

$ cat .ruby-version 
2.3.1

rbenv はこれを読み取って使うバージョンを選んでくれる。

$ ruby --version     
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

rbenv local --unset コマンドを実行すれば元のバージョンに戻る。

$ rbenv local --unset
$ ruby --version  
ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin15]

あるいは、単にファイルを削除してしまっても構わない。

$ rm .ruby-version

シェルで使うバージョンを一時的に切り替える

シェルで使うバージョンを一時的に指定したいときは rbenv shell コマンドを使う。

$ rbenv shell 2.3.1
$ ruby --version
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

これは環境変数 RBENV_VERSION に使うバージョンが指定されることで動作している。

$ env | grep RBENV
RBENV_SHELL=zsh
RBENV_VERSION=2.3.1

これも rbenv local コマンドと同じように、元に戻したいときは --unset オプションを使えばもとに戻る。

$ rbenv shell --unset
$ ruby --version     
ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin15]

あるいは単に環境変数 RBENV_VERSION を消してしまっても構わない。

$ unset RBENV_VERSION

Bundler をインストールする

Ruby のパッケージ管理には Bundler を使うのがデファクトスタンダードになっているみたい。 これを使うとプロジェクトごとに使うパッケージを切り替えることができて vendoring が実現できる。

まずは gem install コマンドで Bundler をインストールする。

$ gem install bundler

インストールすると bundle コマンドが使えるようになる。

$ bundle --version
Bundler version 1.13.6

Bundler を使ってみる

それでは、適当な名前で作業ディレクトリを用意しよう。 これが Ruby で書かれた何らかのプロジェクトを模している。

$ mkdir -p sample
$ cd sample

bundle init コマンドで新しいプロジェクトを用意する。

$ bundle init

すると Gemfile というファイルができる。 これにプロジェクトで使うパッケージを羅列していくみたい。

$ cat Gemfile 
# frozen_string_literal: true
source "https://rubygems.org"

# gem "rails"

初期状態では rails がコメントアウトされた状態で記述されている。

試しに rails のコメントアウトを外して使ってみたい。 そこで GNU sed が使いたいので Homebrew でインストールしてエイリアスを貼っておく。

$ brew install gnu-sed
$ alias sed=gsed

sed コマンドを使って先頭のコメントアウト記号 # を外す。

$ sed -i -e "s:^# gem:gem:" Gemfile
$ cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"

gem "rails"

bundle install コマンドを使うと Gemfile の内容を読み取って gem パッケージをインストールしてくれる。 このとき --path を指定するのをお忘れなく。 もし、これを忘れるとシステムにパッケージがインストールされてしまう。

$ bundle install --path=vendor/bundle
...(省略)...
Bundle complete! 1 Gemfile dependency, 38 gems now installed.
Bundled gems are installed into ./vendor/bundle.

上記で、インストールされたパッケージのコマンド群は vendor ディレクトリ以下にある。 そのため、デフォルトではパスが通っていない。 もし、それらを実行したいときは bundle exec コマンドを経由しよう。

$ bundle exec rails --version
Rails 5.0.0.1

rbenv-binstubs を使って横着する

ただ、上記の bundle exec コマンドを使うのは正直めんどくさいところもある。 そんなときは rbenv-binstubs というツールを使うと楽ができるかもしれない。

まずは、先ほど gem パッケージをインストールしたディレクトリを削除しておく。

$ rm -rf vendor

Homebrew で rbenv-binstubs をインストールする。

$ brew install rbenv-binstubs

次に、また bundle install で gem パッケージをインストールする。 ただし、今度は --binstubs というオプションをつけるところが異なる。

$ bundle install --path=vendor/bundle --binstubs=vendor/bin

インストールできたら rbenv rehash コマンドを実行しておこう。

$ rbenv rehash

すると bundle exec コマンドを使わずとも直接 vendor ディレクトリ以下のコマンドが使えるようになる。

$ rails --version
Rails 5.0.0.1

bundle install コマンドのオプションは何だか長くて忘れそうだから、エイリアスを貼っておくのが良いかな。

$ cat << 'EOF' >> ~/.zlogin
# bundle
which bundle > /dev/null 2 > /dev/null
if [ $? -eq 0 ]; then
  alias bi="bundle install --path=vendor/bundle --binstubs=vendor/bin"
fi
EOF
$ source ~/.zlogin

これで、ひとまず複数バージョンの Ruby をインストールして vendoring できるところまでできた。