sup*_*ary 139 ruby rubygems ruby-on-rails rvm rbenv
我对RVM和rbenv如何实际工作感兴趣.
显然,他们在不同版本的Ruby和gemsets之间进行交换,但这是如何实现的呢?我曾经假设他们只是更新符号链接,但是深入研究代码(我必须承认我对Bash的了解是肤浅的),他们似乎做得比这更多.
Sam*_*son 241
简短说明:rbenv通过挂钩到您的环境中工作PATH.这个概念很简单,但魔鬼在于细节; 完整的勺子.
首先,rbenv创建垫片的所有命令(ruby,irb,rake,gem等)跨红宝石的所有已安装的版本.此过程称为rehashing.每次安装新版本的Ruby或安装提供命令的gem时,rbenv rehash都要运行以确保所有新命令都是shimmed.
这些填充程序位于单个目录中(~/.rbenv/shims默认情况下).要使用rbenv,只需将shims目录添加到您的前面PATH:
export PATH="$HOME/.rbenv/shims:$PATH"
Run Code Online (Sandbox Code Playgroud)
然后,只要您从命令行运行ruby,或运行shebang读取的脚本#!/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版本,然后运行该版本的相应命令.这是如何做:
RBENV_VERSION设置了环境变量,则其值确定要使用的Ruby版本..rbenv-version文件,则其内容用于设置RBENV_VERSION环境变量..rbenv-version当前目录中没有文件,rbenv将在每个父目录中搜索.rbenv-version文件,直到它到达文件系统的根目录.如果找到一个,则其内容用于设置RBENV_VERSION环境变量.RBENV_VERSION仍未设置,则rbenv尝试使用~/.rbenv/version文件的内容进行设置.(您可以使用该rbenv local命令设置特定于项目的Ruby版本,该命令.rbenv-version在当前目录中创建文件.同样,该rbenv global命令会修改该~/.rbenv/version文件.)
使用RBENV_VERSION环境变量,rbenv添加~/.rbenv/versions/$RBENV_VERSION/bin到您的前面PATH,然后执行传递给的命令和参数rbenv exec.瞧!
要彻底了解幕后发生的事情,请尝试设置RBENV_DEBUG=1并运行Ruby命令.rbenv运行的每个Bash命令都将写入您的终端.
现在,rbenv只关心切换版本,但繁荣的插件生态系统将帮助您完成从安装Ruby到设置环境,管理"gemsets"甚至自动化等bundle exec所有事情.
我不太确定IRC支持与切换Ruby版本有什么关系,而rbenv的设计简单易懂,不需要支持.但是,如果您需要帮助,问题跟踪器和Twitter只需点击几下即可.
披露:我是rbenv,ruby-build和rbenv-vars的作者.
mpa*_*pis 18
我写了一篇深入的文章:http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/
基本区别在于shell环境发生了变化:
此外,关于RVM是一回事,它涵盖了更大量的然后就管理红宝石,它比任何其他工具更大量的(还有其他的除了RVM和rbenv:https://twitter.com/#!/mpapis/ status/171714447910502401)
不要忘记在Freenode服务器上的"#rvm"频道中获得IRC的即时支持.
sup*_*ary 15
因此,总结一下上面的优秀答案,RVM和rbenv之间的主要实际区别在于选择了Ruby的版本.
rbenv:
rbenv在路径的开头添加了一个垫片,一个与Ruby同名的命令.当您ruby在命令行键入时,将运行填充程序(因为它也称为"ruby"并且在路径中位于第一位).垫片会查找环境变量或.rbenv_version文件,以告诉它要委派给哪个版本的Ruby.
RVM:
RVM允许您通过调用直接设置Ruby版本rvm use.此外,它还会覆盖cd系统命令.当您cd进入包含.rvmrc文件的文件夹时,将执行文件中的代码.rvmrc.这可以用来设置Ruby版本,或者你想要的任何其他东西.
其他差异:
当然还有其他差异.RVM开箱即用,而rbenv只需要更多的黑客攻击(但不多).两者都是问题的功能性解决方案.
主要区别似乎是何时以及如何切换红宝石.Ruby被切换:
RVM依赖于修改后的cd命令和手动选择Ruby by rvm use.rbenv为所有基本ruby命令使用包装器或"填充程序"作为选择ruby的默认机制.RVM也为gem,rake,ruby等基本命令行工具创建包装器.它们用于例如CronJobs(请参阅http://rvm.io/integration/cron/),但它们不是切换Ruby版本的默认机制.
因此,两种方法都通过覆盖命令和使用包装器来"自动"选择正确的Ruby版本.rvm覆盖像cd这样的shell命令.rbenv会覆盖所有基本的ruby命令,例如ruby,irb,rake和gem.
rvm system
env > before
rvm jruby # or whatever
env > after
diff after before
Run Code Online (Sandbox Code Playgroud)
大概给你:
< 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
Run Code Online (Sandbox Code Playgroud)
它预先说明:
$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/jruby-1.6.6@global/bin
Run Code Online (Sandbox Code Playgroud)
至 $PATH