486

Does this:

gem 'whenever', require: false

mean that the gem needs to be installed, or does it mean it is not required?

Promise Preston
  • 24,334
  • 12
  • 145
  • 143
rafamvc
  • 8,227
  • 6
  • 31
  • 34
  • 1
    Most of answers (including accepted one) are about Rails that do the `Bundler.require` by default as I understand. Only Ciro's and Nesha's answers are correct. – Nakilon Sep 17 '18 at 07:47

6 Answers6

520

This means install the gem, but do not call require when you start Bundler. So you will need to manually call

require "whenever"

if you want to use the library.

If you were to do

gem "whenever", require: "whereever"

then bundler would download the gem named whenever, but would call

require "whereever"

This is often used if the name of library to require is different than the name of the gem.

x-yuri
  • 16,722
  • 15
  • 114
  • 161
Rob Di Marco
  • 43,054
  • 9
  • 66
  • 56
  • 135
    @VenkatD. sometimes you want to install certain gems but you don't want to load them in to every process. I have a particular rake task that I want to invoke periodically on Heroku through their schedular add-on. This particular rake task requires certain gems that the rest of the application doensn't need. So I `:require => false` these particular gems and explicitly `require "thegem"` from the rake task. This would then save memory in the main app processes and startup time etc. App performance, however, should not be affected even if you require these additional gems in every process. – Michael van Rooijen Aug 14 '12 at 23:52
  • "This is often used if the name of library to require is different than the name of the gem." - Thanks! That helped me figure out why a gem I was using was not auto-required. – ErJab Apr 26 '13 at 07:26
  • 6
    @MichaelvanRooijen - great points, however: "App performance, however, should not be affected even if you require these additional gems in every process". I don't think that's true. Allocating objects takes work, and the GC has to run through all of them each time, so more = slower, according to http://confreaks.com/videos/2668-gogaruco2013-measuring-ruby – Nathan Long Oct 12 '13 at 14:11
  • @NathanLong if you actually /use/ the gems. It depends on what you're doing. I was talking in the context of using `:require => false` or not. Even if you require the gem but don't actually instantiate objects it won't matter, and potentially only affects boot times to load the code base for that gem. E.g. `Post.limit(100_000).map(&:title)` destroys performance so you don't do this. However, these methods are available in memory. Instead you'd do `Post.limit(100_000).pluck(:title)`. I of course I agree that if you actually /use/ included gems, it would slow down. – Michael van Rooijen Oct 17 '13 at 17:50
  • 1
    @MichaelvanRooijen - In practice, you're right, it won't generally matter unless you use the library. But requiring a gem will at least load its main file in lib, and probably it does more requires of its own. Even if you `require 'yaml'`, you now have the `YAML` module as an object in memory. – Nathan Long Oct 17 '13 at 19:31
  • 2
    What if you want to set require to false and the library name is different to the gem name as well? – Peter-Jan Celis Jan 04 '14 at 15:35
  • 2
    @Peter-JanCelis In that case you would just set `:require => false` and then in your code have a `require 'library_name_here'` – Rob Di Marco Jan 05 '14 at 13:38
  • One such example is the guard-rspec gem, per the instructions you're supposed to include `gem 'guard-rspec', require: false` in the Guardfile, Per https://github.com/guard/guard-rspec – Emeka Feb 25 '16 at 04:50
  • Does this make any difference if I am declaring a gem in a Gemfile for a ruby script, where I have to manually require gems anyway? – Chris Scott Jan 20 '17 at 16:53
84

You use :require => false when you want the gem to be installed but not "required".

So in the example you gave: gem 'whenever', :require => false when someone runs bundle install the whenever gem would be installed as with gem install whenever. Whenever is used to create cron jobs by running a rake task but isn't usually used from within the rails (or other framework if not rails) application.

So you can use :require => false for anything that you need to run from the command line but don't need within your code.

gduq
  • 1,434
  • 11
  • 13
75

require: false tells Bundler.require not to require that specific gem: the gem must be required explicitly via require 'gem'.

This option does not affect:

  • bundle install: the gem will get installed regardless

  • the require search path setup by bundler.

    Bundler adds things to the path when you do either of:

    • Bundle.setup
    • which is called by require bundler/setup
    • which is called by bundle exec

Example

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

Then the following won't raise exceptions:

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

On GitHub for you to play with it.

Rails usage

As explained in the initialization tutorial, the default Rails template runs on startup:

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

config/boot.rb contains:

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

which does the require 'bundler/setup' and sets up the require path.

config/application.rb does:

Bundler.require(:default, Rails.env)

which actually requires the gems.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • Note that using `require 'faker` might not use the correct gem version, specifically if you're Gemfile points to a git ref. – dazonic Oct 02 '15 at 08:35
  • @dazonic is Haml any different on the example? – Ciro Santilli OurBigBook.com Oct 02 '15 at 08:37
  • Although not specified in the docs, while [Bundler::setup](https://www.rubydoc.info/github/bundler/bundler/Bundler.setup) does a "cut" of the available gems (specified in the groups), [Bundler::require](https://www.rubydoc.info/github/bundler/bundler/Bundler.require) (on specific groups) seems to be the one that actually installs the path to the gem (it also does the cut, if `setup` was not called previously). So `Bundler::require` should be called regardless if `required: false` was specified in the _Gemfile_ (otherwise a `LoadError` will follow when calling `require 'gem-name'`) – rellampec Jul 07 '23 at 02:19
19

Whenever you specify a Gem in your Gemfile and run bundle install, bundler will go and install specified gem and load code for that Gem in you app by putting require 'whenever' this way bundler will load code for all of your Gems in your Rails app, and you can call any method from any Gem without any pain, like you do most of the time.

but Gems like whenever, faker or capistrano are something which you do not need in your app code you need whenever code in your schedule.rb file to manage crons and capistrano code in deploy.rb file to customize deployment recipe so you need not to load code for these gems in your app code and wherever you want to call any method from these Gems you can manually require thsese gems by yourself by putting require "whenever" . so you put :require => false in your Gemfile for these Gems, this way bundler will install that Gem but not load code for that Gem itself, you can do it whenever you want by simply putting like require 'whenever' in your case.

Subhash Chandra
  • 3,165
  • 1
  • 27
  • 30
6

Analogy to Explain

## Gemfile
gem "university_degree", require: false
gem "dealing_with_boss" 
  • "dealing_with_boss" - loaded into memory and ready to go.

  • degree gem - not "needed"....you need to manually require it, in order to use it.

BenKoshy
  • 33,477
  • 14
  • 111
  • 80
2

In order to require gems in your Gemfile, you will need to call Bundler.require.

You can prevent bundler from requiring the gem with require: false, but it will still install and maintain the gem. Check this out for a more detailed explanation.

Nesha Zoric
  • 6,218
  • 42
  • 34