web-dev-qa-db-ja.com

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

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

明らかに、彼らはRubyとgemsetsの異なるバージョン間でスワップしますが、これはどのように達成されますか?表面的です)彼らはこれ以上のことをしているようです。

137
superluminary

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

まず、rbenvは、インストールされているすべてのRubyバージョンにわたって、すべてのコマンド(Rubyirbrakegemなど)に対してshimsを作成します。このプロセスはrehashingと呼ばれます。 Ruby)の新しいバージョンをインストールするか、コマンドを提供するgemをインストールするたびに、rbenv rehashを実行して、新しいコマンドがシムされるようにします。

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

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

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

各シムは、rbenv execを順に実行する小さなBashスクリプトです。したがって、パスにrbenvを使用すると、irbrbenv 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がパスにない場合に実行されるバージョン。

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

Rbenvは、RBENV_VERSION環境変数を使用して、~/.rbenv/versions/$RBENV_VERSION/binPATHの前に追加し、rbenv execに渡されたコマンドと引数を実行します。出来上がり!

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


現在、rbenvは単にバージョンの切り替えに関心を持っていますが、プラグインのエコシステムの繁栄は、 Rubyのインストール から 環境のセットアップ管理gemsets " そして偶数 自動化bundle exec

IRCサポートがバージョンRubyバージョンの切り替えに関係しているか、そしてrbenvはサポートを必要としないほどシンプルで理解しやすいように設計されています。助けが必要な場合は、問題追跡ツールとTwitterを数回クリックするだけです。

開示:私はrbenv、Ruby-build、およびrbenv-varsの著者です。

239
Sam Stephenson

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

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

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

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

Freenodeサーバーの "#rvm"チャネルでIRC=で取得するインスタントサポートを忘れないでください。

18
mpapis

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

rbenv:

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

RVM:

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

その他の違い:

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

15
superluminary

主な違いは いつ、どのようにRubyが切り替えられるか 。Rubyが切り替えられる場合:

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

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

したがって、両方の方法は、コマンドを上書きしてラッパーを使用することにより、正しいバージョンを自動的に選択します。Rubyコマンドは、cdなどのシェルコマンドをオーバーライドします。rbenvは、すべての基本的なRuby Ruby、irb、rake、およびgemとして。

6
0x4a6f4672
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

5
Reactormonk