我最新的Rails项目或多或少,并试图在这个过程中分解很多东西并学习。我在我的gemfile中指定了最新版本的Ruby:
ruby '2.2.3'
我在项目中也有一个.ruby-version
点文件,其中包含以下内容:
2.2.3
除了明显的重复之外,这有什么问题?这两个公约的目的是什么?如果我只有一个列出我的Ruby版本的约定,为什么我应该有一个(Gemfile)而另一个(dotfile)?
在项目中同时使用两种约定是否完美无缺?
我将成为这个实验项目的唯一维护者,并且不会觉得必须保持这个微妙的重复是一个问题。我不打算为这个项目升级Ruby,如果我这样做,我就不会记得在两个地方都这样做了。除了这个细节,我当然避免在我的应用程序中出现任何重复。代码库。
答案 0 :(得分:22)
它们各自由不同团队在不同时间开发,并由不同的软件使用。
在Gemfile中列出ruby版本是feature in bundler。
由于Gemfile主要仅由bundler使用,因此它主要仅在您运行with bundler时使用bundle exec
,或者为您自动触发bundler的软件(如Rails)。如果您没有使用指定的ruby版本,它的效果就是错误输出并拒绝运行。这是一个要求 - 在这个红宝石下运行,或者我会抛出错误警告你在错误的红宝石下运行。
但是,heroku also pays attention为Gemfile中指定的版本,并将在该版本下运行。 Heroku也决定在捆绑器中使用该功能。但是,您工作站上的大多数其他软件甚至travis都不使用该约定。 (Travis让您编辑.travis.yml ENV以指定要使用的ruby版本)。
Bundler中的功能于2012年8月在Bundler 1.2中引入。
.ruby-version文件首先由第一个ruby版本管理器rvm引入。如果您使用的是rvm,并且切换到带有.ruby-version
文件的项目目录,则rvm会自动将您的shell切换为使用指定的ruby版本。
我不确定rvm什么时候引入了这个功能,但我想在Gemfile之前" ruby"特征。
由于rvm引入了它,其他ruby版本交换软件如rbenv和chruby也采用了它来做同样的事情 - 自动切换到cd
指定的ruby版本到目录中。虽然我认为rbenv和chruby都可能是一个可选功能。
因此,它们是在不同时间引入并由不同软件包支持的不同功能,做了一些不同的事情。
我同意维护它们并让它们保持同步会很烦人。
它们实际上都是可选的,您不需要使用其中任何一个。除非你可能需要使用geoku文件ruby规范来告诉它你希望它运行哪个ruby。
我也不会亲自使用。但是如果你需要在不同的项目中使用不同的ruby版本,并且发现让ruby版本管理器(rvm,rbenv或chruby)自动切换到正确的项目特定的ruby版本,.ruby-version
可能会很方便有用。
除了heroku之外,在Gemfile中列出ruby主要是为了避免犯错,例如在部署时。或者,内部自动部署或CI环境可能会像heroku一样使用它们,或者其他云部署堆栈可能会或已经采用它。我想很多人发现它不太有用 - 这个也是,我不会使用,直到你碰到或看到它正在解决的问题。一些人在Gemfile中列出ruby版本的一个不便之处在于,随着新的红宝石总是出现,你必须一直更新所有的Gemfiles。
一般来说,过去几年的ruby版本都是向后兼容的,这限制了确保你使用精确版本的ruby的必要性,最新的代码将在最新的ruby上运行,甚至如果它最初是为较旧的。
我不相信这两个功能都允许您指定一系列ruby版本,例如2.2.*
或您拥有的内容。
使用其中一种/两种功能,只有在您需要它们或使用它们时才使用它们,您不必使用它们,如果您需要,可以使用它们(如果烦人的话)这两者都做了。
由于Gemfile是实时ruby代码,理论上你可以让你的Gemfile读取你的.ruby-version
文件,并自动将该值用作Gemfile ruby
值。如果你想同时使用两者,并且不要重复自己"用它。我不知道这是否是常见的事情,我只是想到了。但它应该工作正常。
答案 1 :(得分:11)
我认为最好避免两次列出相同的信息,除非有充分的理由 - 即保持干燥。
您可以将ruby版本存储在" .ruby-version"中,然后在Gemfile中执行以下操作:
ruby File.open('.ruby-version', 'rb') { |f| f.read.chomp }
答案 2 :(得分:1)
在您的Gemfile
中使用它:
ruby File.read('.ruby-version').strip
优点: