rbenvは複数のrubyをインストールして、自由に切り替えることができるツールです。

一方、homebrewでインストールしたrubyは、rbenvからはシステムのデフォルトrubyとして扱われます。

それをあえてrbenvの管理ディレクトリ下に置いて、使えるのか試してみました。

結論としては、実現できましたが、rubyのformulaを修正しないといけないので、あえてやるメリットを感じませんでした。やはり素直にシステムのデフォルトとして使うのがきれいだと思います。

無駄とは思いつつ、ruby環境のお勉強として楽しめましたので、とりあえず記事にしてみました。

homebrewのrubyをrbenvで管理下に置いてみる

rbenvユーザーならご承知のとおり、rbenvでインスールしたrubyは

~/.rbenv/versions/2.4.3
~/.rbenv/versions/2.5.0

のようにバージョン毎に格納されています。

一方の、homebrewのrubyも

/usr/local/Cellar/ruby/2.4.3
/usr/local/Cellar/ruby/2.5.0

のようにバージョン毎にインストールされています。

rbenvからhomebrewのrubyを認識させるためには、そのsymlinkをrbenv下につくれば、いいわけです(rbenvの公式サイトにもsymlinkが使えるとあります)。

~/.rbenv/versions/2.4.3
~/.rbenv/versions/2.5.0
# ↓symlink => /usr/local/Cellar/ruby/2.4.3
~/.rbenv/versions/brew-2.4.3

これで、rbenvを設定すれば、homebrewのrubyを実行できるようになりました。

$ rbenv local brew-2.4.3

しかし、gem installでコマンドをインストールして、それを実行したところ、コマンドが見つからない旨のエラーが表示されました。bundlerなどをインストールしても使えないのです。

原因は、homebrewとrbenvで、RubyGemsの実行パスが違うためです。

まず、rbenvの実行パスは、rubyのインストールディレクトリ下にあります。ファイルはRubyGemsのライブラリも含めてすべてこの下に置かれます。

# rbenvのruby
~/.rbenv/versions/2.4.3
# RubyGemsの実行パス
~/.rbenv/versions/2.4.3/bin

一方、homebrewのrubyは、実行パスがインストールディレクトリの外側にあります。

# homebrewのruby
/usr/local/Cellar/ruby/2.4.3 
# RubyGemsの実行パス
/usr/local/bin

rbenvの仕様は、同じ直下にbinが必要なわけです。

# 本来はこうであってほしかった
/usr/local/Cellar/ruby/2.4.3/bin

brewのgem installは、/usr/local/binへインストールしてしまうので、rbenvはコマンドを見つけられません。

RubyGemsの実行パスを変更する

そこで、rbenvの仕様に合うように、RubyGemsの実行パスを変更してみます。

実行パスは、次のファイルで定義されています。

/usr/local/Cellar/ruby/2.4.3/lib/ruby/2.4.3/rubygems/defaults.rb 

homebrewの場合、次のファイルに独自の設定がありまして

/usr/local/Cellar/ruby/2.4.3/lib/ruby/2.4.3/rubygems/defaults/operating_system.rb

次のメソッドに、RubyGemsの実行パスがハードコーディングされています。

def self.default_bindir
  "/usr/local/bin"
end

新しいパスはこんな感じ。

def rubygems_bindir
  "/usr/local/Cellar/ruby/2.4.3/bin"
end

(アップデートを考慮すれば、/usr/local/opt/ruby/binがいいのかもしれません)

これで、gem installは、新しいパスへインストールしますので、bundlerなどが使えるようになりました。

ちなみに、このoperating_system.rbは、rubyのインストール時にFormulaのruby.rbから生成されるので、formulaを修正したほうがhomebrewらしいと思われます。

homebrewの美しさ

このように試してみたわけですが、このような使い方は全然よろしくないと思いました。

homebrewのディレクトリ構成は美しいと思うのです。 パッケージ単位のディレクトリにファイル(実装)がまとめて保管されていて

  /usr/local/Cellar/ruby/2.4.3

次のような標準的なディレクトリ構成下に、symlinkとして配置されています。

 /usr/local/lib/ruby
 /usr/local/lib
 /usr/local/bin

今回の修正はこの整然とした美しさを壊しているだけ・・・と感じます。

(今回の別の解決策として、gem installしたあとで、/usr/local/binのコマンドを、rbenvのbinへsymlinkを貼る、ということも考えられますが・・・)

homebrewのrubyはrbenvのsystemとして使う

というわけで、最初に書いたとおり、homebrewのrubyは、デフォルトのままインストールして、rbenvからシステムのデフォルトrubyとして使っています。

で、必要にディレクトリだけ、rbenvで別のバージョンを指定しています。

# ディレクトリ単位
$ rbenv local 2.4.3

システム全体に設定する場合はこちら

# システム全体
$ rbenv global 2.4.3

ちなみに、Macには、最初からrubyが/usr/bin/rubyとしてインストールされています。 環境変数PATHの/usr/local/bin/usr/binより優先されているので、homebrewの/usr/local/bin/rubyが通常は使われるわけですね。

  1. /usr/local/bin/ruby # homebrewが優先
  2. /usr/bin/ruby # mac標準

Mac標準のrubyを使う場合は、

$ brew unlink ruby

を実行すれば、/usr/local/bin/rubyが削除されるので、/usr/bin/rubyがデフォルトのrubyになります。