分享 RVM 与 Bundler 的爱恨情仇

xiaoronglv · 2014年08月04日 · 最后由 chenyihu 回复于 2016年06月23日 · 16726 次阅读
本帖已被管理员设置为精华贴

自从 2 年前 Sam 帮我搭建了 Ruby 环境,除了升级就再没折腾过。懒,不爱折腾,太花时间,投入产出不成正比。

但是在开发的过程中,越来越多 Rvm & Bundler 的问题摆在了我面前,每次都要请教别人,十分的影响效率。

于是花了一个上午的时间彻底把 Rvm 和 Bundler 的关系梳理了一下。

Rvm

Rvm 用于管理 Ruby 的版本和该版本的 Gem。

Rvm

一开始我很疑惑,为什么同一个 Gem,同一个版本号,要保存四份?

据大牛回答,有些 Gem 需要编译,所以依赖 Ruby 版本。比如在 Ruby 1.9.3 的环境下编译的 libv8 (3.11.8.17)不一定能在 Ruby 2.0.0 中使用。

所以即使相同版本号的 Gem,也要在各个 Ruby 各自编译,各自保存。

Rvm Gemset

事实上 Rvm 在管理 Gem 的方式上要比图一还要复杂 一些,它的内部还有一套 Gemsets 的机制。

我把 Gemset 理解为一个环境,这个环境中罗列了 Gem 的版本号。

Gemset

  1. Ruby 版本
  2. Gemset 环境
  3. Gem 列表

Gemset 大体可分为三类:

  1. @global

    比如:ruby-1.9.3-p448@global

    安装在 @global 中的 Gem 会被其他 Gemset 继承。假如我在 ruby-1.9.3-p448@global 中安装了 bundler-1.1.5,那么 ruby-1.9.3-p448@codecampo 也可以使用 bundler-1.1.5。

  2. @default

    比如:ruby-1.9.3-p448

    若不指定 Gemset,Gem 都安装在默认环境下。

  3. @custom

    自定义的 Gemset,比如

    • ruby-1.9.3-p448@ruby_china
    • ruby-1.9.3-p448@codecampo
    • ruby-1.9.3-p448@19wu

你可以创建一个 ruby-1.9.3-p448@ruby_china 的环境用来跑 Ruby China,你也可以创建 ruby-1.9.3-p448@codecampo 跑 codecampo。

Rvm Gemset Vs Bundler Gemfile 的区别是什么?

很早之前我有类似的疑问:我的每个项目都使用 Bundler 生成 Gemfile、Gemfile.lock 管理版本号和依赖关系。为毛还需要 Rvm Gemset?

我们现在的确不需要!

但,爱过。

Rvm 诞生于 Bundler 之前,并通过 Gemset 这种的式来管理 Gem(作者在此处先入为主,搞错啦,建议大家看楼下 @nightire 大牛的点评)。

随后 Bundler 才兴起,大家几乎都一窝蜂似的用它管理项目中涉及 Gem 的版本号、依赖关系。从而导致了 Rvm 的 Gemset 处于十分尴尬的地位。

1 楼 已删除

思路很清晰。

rvm 下貌似使用每个 gemset 版本都是独立的一套 gems,没看见有软链啊 我觉得 rvm 主要是为了解决 ruby 和 gem 版本的冲突问题(gemset) gemfile 就是为了绑定 gem 版本用的,多个项目 gem 版本有冲突的时候可以用 gemset 解决

从我学习 ruby 开始就美用过 gemset.

#4 楼 @zgm

rvm 为毛不把 gemset 砍掉呀?

#5 楼 @xiaoronglv 因为还有人在用吧。加功能容易减功能难啊……

#5 楼 @xiaoronglv gemset 还是有好处的嘛.. 可以用 rvmrc 自动切换 gemset 环境,然后直接敲命令就是使用这个 gemset 里面的版本。如果用 bundler 的话就要 bundle exec

#8 楼 @nightire

关于先后顺序,十分的不好意思,我确实搞错了。

http://sirupsen.com/get-started-right-with-rvm/

When I wrote this article, bundler wasn’t commonly found in Ruby projects as it is now.

我在这篇文章中读到这个观点,没有仔细考证,结果误人子弟啦。在 Github 上,Bundler 的项目更早一些。

顺便请教一个问题:现在还有人使用 gemset 吗?

貌似很多人讨厌 gemset,就转到更简单的 rbenv 了。

bundler 先出来还是 rvm 的 gemset 先出来就不太清楚了,我只知道 gemset 这东西在 rails2 时代,到处横行,一台服务器上装多几个 rails app,不用 gemset 我记得会很麻烦,会有各种冲突出现。就算用了,也会有各种麻烦的问题。 bundler 啥时候出来啥时候开始就不太清楚了,但是我只知道 rails 有了 Gemfile(Bundler) 之后,gemset 存在的意义似乎已经不大了。因为用了 bundler 之后再也没有以前那些痛苦的问题,以至于都忘记 gemset 的存在了。

这两者解决的是同一个问题吗?是的,对于我来说是的,对于你来说是不是我就不知道了,我不知道 gemset 还能解决什么问题。而且从一开始,我就觉得 gemset 这东西就是个错误的解决办法,以至于很容易一团乱麻。

#11 楼 @nightire 所以,就使用便利性上面来说,binstub 完爆 gemset

#12 楼 @bluecoda 对啊,只是有不少人不会去定义下 $PATH,还在没完没了的 ./bin/rails,看的人蛋疼,除却这一点,binstub 实在是极好的一种方案。不过话说回来,gemset 也不复杂,不就是创建项目的时候 --create --default 一句么,以后都是自动切换的。麻烦的是管理不善导致的混乱,这个真是要看人了。gemset 还有简单方便的导入/导出特性,这个就完全和 binstub 没关系了。

改下标题吧

没用过 rvm,我一般是用源码编译安装 ruby,然后 gem install rails 安装 rails

只知道有 gemset 这个东西,但从来没用过。

gemset 没有用过,一般都是用 gem

#13 楼 @nightire 后来为了避免老是要输入 ./bin/rails, 还可以引入 direnv 工具..进入目录自动修正 PATH 变量。

#18 楼 @ruohanc 其实手动添加 ./bin$PATH 最前面就可以了,一直这么做,很聪明,也没啥问题。

gemset 还是好用啊,统一全队开发版本,进入项目,自动切换等等。

#19 楼 @nightire 不要将任何.开头的东西加到$PATH里,很危险的,比方说有人知道你这么干,特意搞个”开源项目“什么的,然后你习惯性 clone 下来,cd 进去,ls 一下,然后就中招了,因为里面有个 ./bin/ls文件,内容是

#!/bin/sh
rm -rf ~

真没人注意到标题的 bundler 写错了?

#21 楼 @comensontin 这个确实猛,还有共享目录也会中标

#21 楼 @comensontin 嗯,你说的是对的,这个问题的确是一个安全隐患,值得说明一下。我还好只是在本地开发用机上这么干,纯粹图省事而已。不过话说回来如果我 ls 一下就会问我要密码,那傻子也知道不对劲了,我没有一直用 root 干活的习惯。

#24 楼 @nightire 话说 rm -rf ~ 会提示密码么?从来没试过

#18 楼 @ruohanc direnv 竟然是 go 写的

我是用 gemset 来保证 rake 和 bundler 的版本的 有的老项目没有人修护,一些 rake 或是 bundler 的升级会造成项目的破坏 工具都是适用环境的,你在本机上会觉得那么多 gemset,占那么大空间不合算 但到了产生环境,几 G 的空间不算什么,在稳定压倒一些的前提下,老板不会让你升级老版本的环境

RVM 解释的挺好的,最后一段有点儿虎头蛇尾的感觉=,=

我一直都用 RVM 管理不同的项目环境,主要是当有太多不同版本的 Ruby 和 Gem 的时候,我觉得 RVM 的环境感觉比较纯净吧。(新人学习中.... 虽然没遇到,不同版本的同一个 GEM 没准会有冲突?)

另外,作为精华帖,标题太误导了。我还以为 Bunder 是 RVM 的前身或转世什么的。

@nightire 看帖子进来插一句嘴,你发帖的语气能不能好一些,读起来怪怪的,不能温柔善良幽默和蔼可亲一些吗?人家就是发个帖子而已,你觉得有错你指出来来行了,不能少用一些“可笑”这样的词吗?这个事有那么可笑吗?

./bin 加到 $PATH 的最前面不可取,如果我在项目里面的 bin 里面丢个木马,名字叫做 ls ,然后通过某种手段诱骗你去下载这个项目……

-- update sorry,原来 @comensontin 已经说过了

匿名 #32 2014年08月07日

yea

#30 楼 @dave 可以,你说的对,我改之。

#30 楼 @dave 改过之后多说两句,也不是为了解释什么,就是跟你说一下选择那种方式说话的原因。实际上我对楼主没有任何敌意,也没有轻视的念头,但为什么我回复的语气比较“阴阳怪调”呢?那是因为我从楼主的字里行间读出了一种“潜意识”(当然是我过分敏感了吧),我觉得楼主在做他的研究的时候有种先入为主的念头,那就是“Gemset 对于 RVM 来说是一个鸡肋/败笔”,我觉得这种做学问的态度是不对的,比不做学问还可怕,因为你胡说八道大家都看得出来,一笑置之就罢;但若你长篇累牍,一般人就看不出问题所在,很容易被你误导。最近一段时间因为工作的原因遇到了一些类似的人和事情,生了很大的气,所以魔由心生,不觉得就有些代入感过强了。

当然了,我说话的态度更是不对的,如你所说:若有错误指出来便是,不应在言语上令人难堪,否则也不足以服人,更不要说服众。此后关于 ./bin 追加给 $PATH 的讨论就能侧面反映出这一点,我自己由于很小心所以没有出过什么岔子,但是其他人说的不安全之处更加值得注意,我已经改掉了自己的习惯,也很感谢大家让我涨了这个见识。由此可见学问处处皆可见,莫因先知笑后觉。再次感谢你的提醒,总的来说社区对我是相当宽容的,Ruby 并非我的最强项,但我偶然的发言却也总能得到大家的肯定和鼓励,想想我也的确应该更加柔和厚重,才是一个回报的态度,兄弟的当头棒喝真的很及时,谢在心里不多废话了。

@nightire 很豪爽啊哇哈

@xiaoronglv What software you use to draw the picture ?

#36 楼 @jinleileiking 求改正语法错误>~<有点强迫症……

39 楼 已删除

gemset bundler 两个都在用,一直都很爽。 正如 @nightire 所说,这两个工具解决的是不同的问题。

gemset 很简单,也很好用,也很实用。 配合 rvm rvmrc 就更好用了!

ggg #38 楼 @xiaoronglv give me a link please. There are a lot of skitchs on the web. Sorry for the input method.

#43 楼 @xiaoronglv 箭头那些应该是通过 skitch 加上的,那关系图是用什么画的呢?

被 RVM 和$PATH 和 gemset 折腾了一晚上。。。。。

.net 程序员 按抓,Ruby 进行时

chenyihu ROR 环境搭建小结~强大的 RVM 提及了此话题。 06月23日 07:32
需要 登录 后方可回复, 如果你还没有账号请 注册新账号