[Ruby] homebrewのrubyをrbenvで使う
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
が通常は使われるわけですね。
- /usr/local/bin/ruby # homebrewが優先
- /usr/bin/ruby # mac標準
Mac標準のrubyを使う場合は、
$ brew unlink ruby
を実行すれば、/usr/local/bin/ruby
が削除されるので、/usr/bin/ruby
がデフォルトのrubyになります。