1

这是更多好奇的问题,而不是问题。当系统上存在多个版本时,使用命令时选择哪些版本require?故事的背景是:我正在bundler项目(不是Rails项目)中实现gem。我没有问题,但其他开发人员有问题,经过快速调查,我意识到我没有使用

require "bundler/setup"

这基本上加载了捆绑的宝石。快速修复,但它让我想知道通过 ruby​​gems 的 ruby​​ 如何决定使用哪些宝石。由于 Ruby 应用程序使用了其中一个 gem 的旧版本,而不是新版本,因此代码损坏了。这意味着它不使用“最新”的宝石,那么它背后的逻辑是什么?

更新

为了进一步解释这个问题,假设你有宝石foo-1.0.1foo-1.0.2当你说,require 'foo'红宝石如何知道要加载哪个?

4

2 回答 2

3

在 Ruby 中,你require是一个文件而不是一个gem。如果在当前加载路径上找不到该文件,Rubygems 将在已安装的 gems 中搜索具有该名称的文件,如果找到,则 gem 被激活(意味着它被添加到 laod 路径)并且文件是然后需要。lib通常,gem 在其目录中会有一个同名的文件。只能激活一个版本的 gem。

被激活的 gem是与任何其他已激活 gem 兼容的最新版本。通常这只是意味着将激活安装的最新版本,但如果您已经激活了一些声明依赖于您尝试激活的早期版本的 gem 的 gem,则可能不是这种情况。

例如,如果您已经安装foo-1.0.1foo-1.0.2安装了,那么require 'foo'(假设他们有一个foo.rb在其lib目录中命名的文件并且没有其他 gem)将导致版本 1.0.2 被激活。但是,如果您还有bar一个依赖于的 gem,则在激活之后1.0.1调用将导致 1.0.1 of被激活。require 'foo'barfoo

此外,如果您尝试以其他顺序要求它们,require 'foo'; require 'bar';那么您将得到类似

Gem::LoadError: Unable to activate bar-1, because foo-2 conflicts with foo (= 1)

这里不能激活bar,这取决于 1.0.1 的版本,foo因为你已经激活了 1.0.2 的版本foo

于 2012-12-12T15:01:48.520 回答
0

如果没有 Bundler,您必须指定所需的每个 gem。例如,

require 'my_gem'
require 'my_other_gem'

但是,Bundler 可以让您使用Gemfile

如果这是你的Gemfile

gem 'my_gem'
gem 'my_other_gem'

调用这将包括所有宝石

require 'bundler/setup'
于 2012-12-11T22:33:14.457 回答