在Gemfile和.ruby-version Dotfile中列出Ruby版本是不好的做法吗?

我最新的Rails项目或多或少都在试验我在这个过程中打破很多东西并学习。 我在我的gemfile中指定了最新版本的Ruby:

ruby '2.2.3'

我在项目中也有一个.ruby-version dotfile,其中包含以下内容:

2.2.3

除了明显的重复之外,这有什么问题? 这两个公约的目的是什么? 如果我只有一个列出我的Ruby版本的约定,为什么我应该有一个(Gemfile)而另一个(dotfile)?

在项目中同时使用这两个约定是完全可以的吗?

我将成为这个实验项目的唯一维护者,并且不会觉得必须保持这个微妙的重复是一个问题。 我不打算为这个项目升级Ruby,如果我这样做,我不会在两个地方都有这个问题。 除了这个细节,我当然避免在我的应用程序的代码库中出现任何重复。

它们各自由不同的团队在不同时间开发,并由不同的软件使用。

在Gemfile中列出ruby版本是bundler中的一项function 。

由于Gemfile主要仅由bundler使用,因此它主要仅在您运行with bundler时使用bundle exec ,或者使用自动触发bundler的软件(如Rails)。 如果您没有使用指定的ruby版本,它的效果就是错误输出并拒绝运行。 这是一个要求 – 在这个ruby下运行,或者我会抛出一个错误警告你在错误的ruby下运行。

但是, heroku也会关注 Gemfile中指定的版本,并将在该版本下运行。 Heroku也决定在捆绑器中使用该function。 但是大多数其他软件,在您的工作站上,甚至是travis ,都没有使用该惯例。 (Travis让您编辑.travis.yml ENV以指定要使用的ruby版本)。

Bundler中的function于2012年8月在Bundler 1.2中引入。

.ruby-version文件最初是由第一个ruby版本管理器rvm引入的。 如果您正在使用rvm,并且切换到带有.ruby-version文件的项目目录,则rvm将自动将您的shell切换为使用指定的ruby版本。

我不确定rvm何时引入了这个function,但我认为在Gemfile“ruby”function之前。

由于rvm引入了它,其他ruby版本切换软件如rbenv和chruby也采用了它来做同样的事情 – 自动切换到cd进入目录时指定的ruby版本。 虽然我认为rbenv和chruby都可能是一个可选function。

因此,它们是在不同时间引入并由不同软件包支持的不同function,做了一些不同的事情。

我同意维护它们并使它们保持同步会很烦人。

它们实际上都是可选的,您不需要使用任何一个。 除了你可能需要使用geoku文件ruby规范来告诉它你想要它运行哪个ruby。

我个人也没用。 但是如果你需要在不同的项目中使用不同的ruby版本,并且发现让ruby版本管理器(rvm,rbenv或chruby)自动切换到正确的项目特定的ruby版本, .ruby-version可能会很有用。 。

除了heroku之外,在Gemfile中列出ruby主要是为了避免犯错,例如在部署时。 或者,内部自动部署或CI环境可能会像heroku一样使用它们,或者其他云部署堆栈可能会或已经采用它。 我想很多人发现它不太有用 – 这个也是,我不会使用,直到你碰到或看到它正在解决的问题。 一些人在Gemfile中列出ruby版本的一个不便之处在于,随着新的ruby总是出现,你必须一直更新所有的Gemfiles。

一般来说,过去几年的ruby版本都非常向后兼容,限制了确保使用精确版本的ruby的需要,最近的代码将在最新的ruby上运行,即使它最初是写的对于较旧的人。

我不相信这两个function都允许你指定一系列ruby版本,比如2.2.*或者你有什么。

使用其中一种/两种function,只有在需要它们时才使用它们或者发现它们很有用,你不必使用它们,如果你需要它们,那么两者都很好(如果烦人的话)。

由于Gemfile是实时ruby代码,理论上你可以让你的Gemfile读取.ruby-version文件并自动使用该值作为Gemfile ruby值。 如果你想同时使用它们,并且“不要重复自己”。 我不知道这是否是常见的事情,我只是想到了。 但它应该工作正常。

我认为最好避免两次列出相同的信息,除非有充分的理由 – 即保持干燥。

您可以将ruby版本存储在“.ruby-version”中,然后在Gemfile中执行以下操作:

 ruby File.open('.ruby-version', 'rb') { |f| f.read.chomp } 
Interesting Posts