这是更多的好奇心问题而不是问题。当系统中存在许多版本时,使用require
命令时会选择哪些版本?故事的背景是:我在项目中实现了bundler
gem(而不是Rails项目)。我没有任何问题,但其他开发人员遇到问题,经过快速调查,我意识到我没有使用
require "bundler/setup"
基本上加载了捆绑的宝石。快速修复,但它让我想知道红宝石如何通过rubygems决定使用哪些宝石。因为代码破坏了,因为Ruby应用程序使用了其中一个宝石的旧版本,而不是更新版本。意思是它没有使用“最新”的宝石,那么背后的逻辑是什么?
更新
要进一步解释这个问题,请说明你有宝石foo-1.0.1
和foo-1.0.2
时,require 'foo'
ruby如何知道要加载哪一个?
答案 0 :(得分:3)
在Ruby中,您require
一个文件而不是 gem 。如果在当前加载路径中找不到该文件,Rubygems将在已安装的gems中搜索具有该名称的文件,如果找到一个gem 已激活(意味着它被添加到laod path)然后需要该文件。通常,gem将在其lib
目录中具有同名文件。只能激活一个版本的gem。
激活的gem是可用的最新版本,与任何其他激活的宝石兼容。通常情况下,这只是意味着安装的最新版本将被激活,但如果您已经激活了一些宝石,这些宝石声明了对您尝试激活的宝石的早期版本的依赖性,则情况可能并非如此。
例如,如果您安装了foo-1.0.1
和foo-1.0.2
,那么require 'foo'
(假设他们的foo.rb
目录中有一个名为lib
的文件,而不是其他gem确实会导致版本1.0.2被激活。但是,如果您还拥有依赖于bar
的gem 1.0.1
,那么在require 'foo'
被激活后调用bar
将导致foo
的1.0.1被激活。
此外,如果您尝试以其他顺序要求它们require 'foo'; require 'bar';
,那么您将获得类似
Gem::LoadError: Unable to activate bar-1, because foo-2 conflicts with foo (= 1)
此处您无法激活bar
,这取决于foo
的1.0.1版,因为您已激活foo
的1.0.2版。
答案 1 :(得分:0)
如果没有Bundler,你必须指定你想要的每个宝石。如,
require 'my_gem'
require 'my_other_gem'
但是,Bundler可以让您使用Gemfile
如果这是您的Gemfile
gem 'my_gem'
gem 'my_other_gem'
调用此选项将包括所有宝石
require 'bundler/setup'