RVMとrbenvは実際にどのように機能しますか?


140

RVMとrbenvが実際にどのように機能するかに興味があります。

明らかに、Rubyとgemsetの異なるバージョン間で交換しますが、これはどのようにして実現されますか?私はそれらがシンボリックリンクを単に更新していると想定していましたが、コードを掘り下げた(そして私はBashの私の知識は表面的なものであることを認めなければなりません)彼らはこれ以上のことをしているようです。

回答:


241

簡単な説明:rbenvは、環境のにフックすることで機能しますPATH。概念は単純ですが、悪魔は細部にあります。以下の完全なスクープ。

まず、rbenvが作成したシムすべてのコマンドのために(rubyirbrakegemなど)ルビーのすべてのインストールバージョン間。このプロセスは、リハッシュと呼ばれます。Rubyの新しいバージョンをインストールするか、コマンドを提供するgemをインストールするたびにrbenv rehash、新しいコマンドがシムされていることを確認するために実行します。

これらのシムは単一のディレクトリ~/.rbenv/shimsにあります(デフォルト)。rbenvを使用するには、shimディレクトリをあなたの前に追加するだけですPATH

export PATH="$HOME/.rbenv/shims:$PATH"

その後ruby、コマンドラインから実行するか、シバンがと表示するスクリプトを実行する#!/usr/bin/env rubyと、オペレーティングシステムが~/.rbenv/shims/ruby最初にそれを見つけrubyて、インストールした他の実行可能ファイルの代わりに実行します。

各シムは、実行される小さなBashスクリプトですrbenv exec。したがって、パスにrbenvを使用すると、irbと同等でありrbenv exec irb、とruby -e "puts 42"同等rbenv exec ruby -e "puts 42"です。

このrbenv execコマンドは、使用するRubyのバージョンを判別し、そのバージョンに対応するコマンドを実行します。方法は次のとおりです。

  1. RBENV_VERSION環境変数が設定されている場合、その値によって、使用するRubyのバージョンが決まります。
  2. 現在の作業ディレクトリに.rbenv-versionファイルがある場合は、その内容を使用してRBENV_VERSION環境変数を設定します。
  3. .rbenv-version現在のディレクトリにファイルがない場合、rbenv .rbenv-versionは、ファイルシステムのルートに到達するまで、各親ディレクトリでファイルを検索します。見つかった場合は、その内容を使用してRBENV_VERSION環境変数を設定します。
  4. RBENV_VERSIONそれでも設定されていない場合、rbenvは~/.rbenv/versionファイルの内容を使用して設定しようとします。
  5. どこにもバージョンが指定されていない場合、rbenvは「システム」Rubyを使用することを想定しています。つまり、rbenvがパスにない場合はどのバージョンでも実行されます。

(プロジェクト固有のRubyバージョンは、現在のディレクトリにファイルrbenv localを作成するコマンドで設定でき.rbenv-versionます。同様に、rbenv globalコマンドは~/.rbenv/versionファイルを変更します。)

武器にRBENV_VERSION、環境変数、rbenvが追加されます~/.rbenv/versions/$RBENV_VERSION/bin、あなたの前にPATH、その後に渡されたコマンドと引数を幹部rbenv exec。出来上がり!

内部で何が起きているのかを詳しく調べるにはRBENV_DEBUG=1、Rubyコマンドを設定して実行してみてください。rbenvが実行するすべてのBashコマンドは、端末に書き込まれます。


さて、rbenvはちょうど切り替えのバージョンに関係しているが、プラグインの盛んな生態系があなたからすべてを行うのに役立ちますルビーをインストールするには、ご使用の環境をセットアップし「gemsets」を管理しても、自動化しますbundle exec

IRCのサポートがRubyのバージョンの切り替えとどう関係しているかはよくわかりません。rbenvは、サポートを必要としないようにシンプルで理解しやすいように設計されています。しかし、あなたが助けを必要とするならば、問題追跡とTwitterはほんの数クリックの距離です。

開示:私はrbenv、ruby-build、およびrbenv-varsの作成者です。


14
そのような素晴らしい答えを与えるために時間を割いていただきありがとうございます。
superluminary

2
うわー、そのような包括的で理解可能な説明に感謝します。自然生まれの先生。
racl101 2012年

ねえ、サム、この答えは2年前なので、更新しますか?確かにその時以来、rbenvで何かが変更されています。
ナキロン2014

いいえ。私が今まで見た中で最高のハッカーの説明。ここで変更する必要がある唯一の更新は、rbenv-gemsetへのリンクに対するものだと思います(リンクはまだそこに到達します。これはリダイレクトからのもう1つの追加ステップです)。
Jeffrey 'jf' Lim

18

詳細な記事を書きました:http : //niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/

基本的な違いは、シェル環境が変更される場所です。

  • RVM:Rubyを変更すると変更されます。
  • rbenv:Ruby / gem実行可能ファイルを実行すると変更されます。

また、RVMについては、ルビーを管理するだけでなく、他のツールよりもはるかに多くカバーしています(RVMとrbenv以外には他にもあります:https ://twitter.com/#!/mpapis/ status / 171714447910502401

Freenodeサーバーの「#rvm」チャネルでIRCを利用してすぐにサポートできることを忘れないでください。


1
おかげで、両方のコミュニティの人々が参加するのは本当に素晴らしいことです。
スーパールミナリー

15

上記の優れた答えを要約すると、RVMとrbenvの主な実用的な違いは、Rubyのバージョンが選択されたときです。

rbenv:

rbenvは、パスの先頭にシムを追加します。これは、Rubyと同じ名前のコマンドです。あなたが入力するとruby、コマンドラインで(それはまた、「ルビー」と呼ばれ、パスに最初に来ているので)、シムが代わりに実行されます。シムは、環境変数または.rbenv_versionファイルを探して、委任するRubyのバージョンを指示します。

RVM:

RVMでは、を呼び出すことでRubyのバージョンを直接設定できますrvm use。さらに、cdシステムコマンドもオーバーライドします。ときにあなたがcd含まれているフォルダに.rvmrcファイルを、内のコード.rvmrcファイルが実行されます。これは、Rubyのバージョンやその他の好きなものを設定するために使用できます。

その他の違い:

もちろん他にも違いがあります。RVMにはすぐに使えるgemsetがありますが、rbenvにはもう少しハッキングが必要です(ただしそれほど多くはありません)。どちらも問題に対する機能的な解決策です。


6

主な違いは、ルビーがいつどのように切り替えられるかです。Rubyが切り替わります。

  • RVMの場合は手動で(rvmを使用)、またはディレクトリの変更中に自動的に
  • rbenvの場合、rubyコマンドが実行されるたびに自動的に

RVMは、変更されたcdコマンドとによるRubyの手動選択に依存していrvm useます。rbenvは、rubyを選択するデフォルトのメカニズムとして、すべての基本的なrubyコマンドにラッパーまたは「shims」を使用します。RVMは、gem、rake、rubyなどの基本的なコマンドラインツールのラッパーも作成します。これらは、たとえばCronJobs(http://rvm.io/integration/cron/を参照)で使用されますが、Rubyバージョンを切り替えるデフォルトのメカニズムではありません。

したがって、どちらの方法でも、コマンドを上書きしてラッパーを使用することにより、適切なRubyバージョンを「自動的に」選択します。rvmは、cdなどのシェルコマンドをオーバーライドします。rbenvは、ruby、irb、rake、gemなどのすべての基本的なrubyコマンドをオーバーライドします。


5
rvm system
env > before
rvm jruby # or whatever
env > after
diff after before

およそあなたに与える:

< GEM_HOME=$HOME/.gem/ruby/1.9.1
---
> GEM_HOME=$HOME/.rvm/gems/jruby-1.6.6
< GEM_PATH=$HOME/.gem/ruby/1.9.1
---
> GEM_PATH=$HOME/.rvm/gems/jruby-1.6.6:$HOME/.rvm/gems/jruby-1.6.6@global
*bunch of rvm_*
> MY_RUBY_HOME=$HOME/.rvm/rubies/jruby-1.6.6
> RUBY_VERSION=jruby-1.6.6
> IRBRC=$HOME/.rvm/rubies/jruby-1.6.6/.irbrc

そしてそれは付加します:

$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/jruby-1.6.6@global/bin

$PATH

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.