Ruby 什么';s bundle.setup和bundle.require之间的区别

Ruby 什么';s bundle.setup和bundle.require之间的区别,ruby,gem,bundle,Ruby,Gem,Bundle,从中,我了解到有两种方法可以导入您在Gemfile中指定的gem。bundle.setup将“安装程序向Ruby的加载路径添加gem”,而bundle.require将需要所有gem 这两种方法有什么区别?在哪种情况下我应该使用它们中的一个?您必须使用Bundle.setup,并且您可以使用Bundle.require bundler的主要目的是确保Gemfile中定义的gem对应用程序是可见的,也就是说,这里提到的所有gem都是在提到的版本中,但不是一个。为此,需要调整加载路径。这是通过Bun

从中,我了解到有两种方法可以导入您在
Gemfile
中指定的gem。
bundle.setup
将“安装程序向Ruby的加载路径添加gem”,而
bundle.require
将需要所有gem


这两种方法有什么区别?在哪种情况下我应该使用它们中的一个?

您必须使用
Bundle.setup
,并且您可以使用
Bundle.require

bundler的主要目的是确保Gemfile中定义的gem对应用程序是可见的,也就是说,这里提到的所有gem都是在提到的版本中,但不是一个。为此,需要调整加载路径。这是通过
Bundle.setup
完成的


要实际使用gems,必须将它们加载到应用程序中。这可以使用大量的
require
语句手动完成,也可以使用
Bundle.require
为Gemfile中列出的所有gem(或仅某些组)自动完成。但是,这只有在如上所述调整加载路径后才可能。

Bundler.setup
修改加载路径,因此您可以执行类似于
需要“一些gem”
这样的操作,它们会起作用。它允许你“手工”需要宝石。在Bundler使用Rubygems之前,您可以通过
要求使用“Rubygems”
获得大致相同的效果

Bundler.require(:default)
另一方面,实际上需要Gemfile中的所有gem(假设您不使用组;否则,如果您提供参数,则需要指定组中的gem)。它是一组
require'some_gem'
语句的简写


看。请注意,他们说在执行
bundler.require
之前必须执行
require'bundler/setup'
,但实际上这通常不是必需的。我几乎从不使用
Bundler.setup
(或
require'Bundler/setup
),因为我通过
Bundler.require
)需要所有gem。

Bundle.setup
对于最近的Bundler版本来说不是必需的。 事实上,当您运行
Bundler.require
时,它总是试图为您设置正确的
$LOAD\u PATH

唯一需要的是:


需要“bundler”
捆绑机

我将在Rails的上下文中回答这个问题。我在回顾Rails初始化过程时遇到了“bundler/setup”和bundler.require。记住Bundler的目标:安装您需要的gems,并确保这些gems是Rails应用程序中唯一需要的gems。这就是它与Rails的工作原理:

在初始化中,Rails环境首先加载bin/Rails的内容。它需要两个重要文件:

require_relative '../config/boot'
require 'rails/commands'
这里的配置/引导是最关键的。它首先将Gemfile存储在环境变量中,然后运行bundler/setup

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
我注意到的一件事是,通过设置环境变量BUNDLE_Gemfile,显然可以选择使用不同的Gemfile。但更重要的是,由于“bundler/setup”,$LOAD\u路径发生了更改。通常RubyGems有一个默认的$LOAD_路径,当您使用“require”时,它将在其中搜索文件。好的,bundler/setup从$LOAD_路径中删除gems的所有路径(这会反转RubyGems所做的任何加载路径工作)。然后,它只将Gemfile.lock中gem的加载路径添加回$load\u路径。现在,您唯一需要文件的gems是Gemfile中的gems

同样有趣的是,尽管RubyGems有一个默认的$LOAD_路径,在使用“require”时会进行搜索,但您仍然必须使用“require”。这些宝石不是必须的。但是,当您将Bundler与Rails一起使用时,不需要GEM文件中的任何GEM。这是如何实现的?这是由Bundler.require处理的!在bin/rails文件中,有一行:

APP_PATH = File.expand_path('../../config/application',  __FILE__)
应用程序路径刚刚设置在这里。没有加载。但是,当您运行rails server之类的程序时,将使用APP_PATH,因此将加载config/application.rb文件,因此如下所示:

require 'rails/all'
Bundler.require(*Rails.groups)

config/application.rb在Rails引导后运行,在上面的内容中,Bundler.require需要传递给它的所有组中的所有gem。(“组”指的是您在GEM文件中指定的组。)Rails.groups在开发模式下运行Rails时将为[:default,:development],在生产模式下运行[:default,:production],依此类推。默认组包括任何组下未列出的所有宝石。因此,Bundler将在您的Gemfile中查找属于这些组的gem,并调用它找到的每个gem的require。

如果我理解正确,
Bundler.setup
+一堆
require
语句等于
Bundler.require
,对吗?有关为什么应该使用Bundler安装程序的可靠理由,请参阅和(而不是require),然后手动要求依赖项。