为什么虾宝石安装轨道 3.x 时已经有轨道 2.x



我安装了rails(2.3.5)和prawn(0.12.0)。当我安装 prawnto 时,gem 也会rails 3.2.6 版安装。

prawnto的依赖关系是:

prawn >= 0
rails >= 2.1

prawnto依赖项已经存在时,为什么要 gem 安装 Rails 3.x?

tl;dr Use Bundler.它摇滚。

好吧,这基本上取决于依赖解析在 RubyGems 中的工作方式。如果你对它不是很熟悉,请像这个XKCD漫画中的入门面板一样快速上手。RubyGems 依赖管理和 Primer 故事情节在复杂性方面非常相似。

当一个 gem 指定了 (比如 rails >= 2.1 的依赖项时,当您去安装该 gem 时,RubyGems 会方便地忽略您当前已安装的所有 gem,然后查询 Web API 以查找大于或等于 2.1 的绝对最新版本的 Rails。

在撰写本文时,它将找到版本3.2.6,因此将尽职尽责地安装该版本的 Rails,因为它符合依赖要求。它还将安装Rails的每个依赖项,以及它们的依赖项,以及子依赖项,直到没有安装依赖项的gem

我不会确切地讨论它是如何工作的,因为当我想到它时,它会让我的视力变得模糊。


现在,如果您使用的是非纯 RubyGems 的东西,例如 Bundler,您将能够拥有这样的 Gemfile:

source 'http://rubygems.org'
gem 'rails', '2.3.4'
gem 'prawnto', '0.1.1'

然后跑bundle install,然后神奇的事情就会发生。Bundler 将找出Gemfile中指定的所有 gem 的依赖关系,以及它们所依赖的 gem,然后仅安装这些 gem。

这意味着如果你prawnto想要 Rails >= 2.1 ,它不会安装 3.2.6,因为还有另一个依赖项说 Rails 必须精确2.3.4。因此,将安装 Rails 2.3.4。

如果您有冲突的版本,其中 gem A 指定了对 ~> 1.0 的 gem B 的依赖关系,

但随后 gem C 指定了 gem B 必须为 '= 0.5.0' 的依赖项,则 Bundler 不会很高兴,并且会引发错误,因为依赖项无法解析。


我真的建议在你的所有Rails项目中使用Bundler。即使是那些在 Rails 2 上运行的。Bundler 网站上有一个页面,它将帮助您开始使用 Rails 2.3 项目和 Bundler。

最新更新