Ruby: Gemfile 中的 'require: false' 是什么意思?

487

这样做:

gem 'whenever', require: false

这意味着需要安装这个 gem,还是说它不是必需的?


1
大多数答案(包括被接受的答案)都是关于Rails默认执行Bundler.require的,据我所知。只有Ciro和Nesha的答案是正确的。 - Nakilon
6个回答

522

这个意味着安装了gem,但在启动Bundler时不会调用require。因此,您需要手动调用它。

require "whenever"

如果您想使用这个库。

如果您要执行的话

gem "whenever", require: "whereever"

然后bundler会下载名为whenever的gem,但会调用{{}}。
require "whereever"

如果要求的库的名称与宝石的名称不同,通常会使用此方法。

136
有时您希望安装特定的 gem,但不想将它们加载到每个进程中。我有一个特定的 rake 任务,我希望通过 Heroku 的调度程序插件定期调用它。该 rake 任务需要某些 gem,而应用程序的其余部分则不需要这些 gem。因此,我使用 :require => false 对这些特定的 gem 进行了设置,并从 rake 任务中显式地 require "thegem"。这将节省主应用程序进程和启动时间等内存。即使在每个进程中都需要这些额外的 gem,也不应该影响应用程序的性能。 - Michael van Rooijen
6
@MichaelvanRooijen - 很有见地,但是:"即使在每个进程中都需要这些额外的宝石,应用程序的性能也不应受影响",我认为这并不正确。分配对象是需要工作的,垃圾回收器每次运行时都必须遍历所有对象,因此对象越多,速度就会变慢,参考http://confreaks.com/videos/2668-gogaruco2013-measuring-ruby。 - Nathan Long
1
在实践中,你是正确的,除非你使用这个库,否则它通常并不重要。但是,需要 gem 至少会加载其 lib 中的主文件,并且可能会进行更多自己的 requires。即使你 require 'yaml',现在你也有了 YAML 模块作为一个对象存在于内存中。 - Nathan Long
2
如果您想将 require 设置为 false,而且库名称与 gem 名称也不同呢? - Peter-Jan Celis
2
@Peter-JanCelis 在这种情况下,您只需设置 :require => false,然后在您的代码中使用 require 'library_name_here' - Rob Di Marco
显示剩余4条评论

84

当您需要安装gem但不需要“require”的时候,可以使用:require => false

所以在您给出的例子中: gem 'whenever',:require => false 当有人运行bundle install命令时,whenever gem将被安装,就像gem install whenever一样。Whenever通常用于通过运行rake任务创建cron作业,但通常不会在Rails(或其他框架,如果不是Rails)应用程序内使用。

因此,您可以将:require => false用于任何需要从命令行运行但不需要在代码中使用的内容。


8
这也适用于你只在一小部分请求中使用的宝石。 - Nathan Long

76

require: false告诉Bundler.require不要强制要求该特定的gem:必须通过require 'gem'显式地要求该gem。

此选项不会影响:

  • bundle install:无论如何都会安装该gem

  • bundler设置的require搜索路径。

    当你执行以下任一操作时,Bundler会将其添加到路径中:

    • Bundle.setup
    • require bundler/setup调用
    • bundle exec调用

示例

Gemfile

source 'https://rubygems.org'
gem 'haml'
gem 'faker', require: false

main.rb

# Fail because we haven't done Bundler.require yet.
# bundle exec does not automatically require anything for us,
# it only puts them in the require path.
begin Haml; rescue NameError; else raise; end
begin Faker; rescue NameError; else raise; end

# The Bundler object is automatically required on `bundle exec`.
Bundler.require

Haml
# Not required because of the require: false on the Gemfile.
# THIS is what `require: false` does.
begin Faker; rescue NameError; else raise; end

# Faker is in the path because Bundle.setup is done automatically
# when we use `bundle exec`. This is not affected by `require: false`.
require 'faker'
Faker

那么以下内容将不会引发异常:

bundle install --path=.bundle
bundle exec ruby main.rb

GitHub上有这个项目供您参考。

Rails使用方法

初始化教程所述,Rails默认模板在启动时运行:

  • config/boot.rb
  • config/application.rb

config/boot.rb包含以下内容:

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])

这段代码执行了require 'bundler/setup'并设置了所需的路径。

config/application.rb的作用是:

Bundler.require(:default, Rails.env)

实际上需要使用gems。


请注意,使用require 'faker'可能不会使用正确的gem版本,特别是如果您的Gemfile指向git ref。 - dazonic
@dazonic,示例中的Haml有什么不同吗? - Ciro Santilli OurBigBook.com
虽然文档中没有明确说明,但是在Bundler::setup执行时,它会对可用的gem(在groups中指定)进行“切割”,而Bundler::require(在特定的groups上)似乎是实际安装gem路径的方法(如果之前没有调用setup,它也会执行切割)。因此,无论_Gemfile_中是否指定了required: false,都应该调用Bundler::require(否则在调用require 'gem-name'时会出现LoadError)。 - rellampec

19
无论何时您在Gemfile中指定Gem并运行bundle install,bundler都会安装指定的Gem并通过放置require 'whenever'来加载该Gem的代码在您的应用程序中。这样,bundler将加载您Rails应用程序中所有Gem的代码,并且您可以像大多数情况下一样调用任何Gem中的任何方法,而无需任何痛苦。
但是像whenever、faker或capistrano之类的Gems不是您在应用程序代码中所需的内容。您需要将schedule.rb文件中的whenever代码用于管理cron,将deploy.rb文件中的capistrano代码用于自定义部署配方,因此您不需要在应用程序代码中加载这些Gems的代码。每当您想从这些Gems调用任何方法时,可以手动自己要求这些gems,只需放置如require "whenever"的命令即可。因此,对于这些Gems,在您的Gemfile中放置:require => false,这样bundler将安装该Gem但不会加载该Gem本身的代码,您可以随时按照您的要求执行它,例如在您的情况下使用require 'whenever'

6

用类比的方式解释

## Gemfile
gem "university_degree", require: false
gem "dealing_with_boss" 
  • "dealing_with_boss"已加载到内存中并准备就绪。

  • degree gem - 不是“必需的”... 您需要手动require它才能使用它。


2
为了在Gemfile中要求gem,您需要调用Bundler.require。您可以使用require: false阻止bundler要求gem,但它仍将安装和维护这个gem。请参考此处以获取更详细的解释。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接