Does this:
gem 'whenever', require: false
mean that the gem needs to be installed, or does it mean it is not required?
Bundler.require
by default as I understand. Only Ciro's and Nesha's answers are correct.
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.
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.
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
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.
require 'faker
might not use the correct gem version, specifically if you're Gemfile points to a git ref.
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.
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.
Analogy to Explain
## Gemfile
gem "university_degree", require: false
gem "dealing_with_boss"
"dealing_with_boss" - always needed - loaded into memory and ready to go.
I rarely need the degree gem. Only when I'm talking to recruiters. So I manually require it, and all of a sudden fancy words like "Black Scholes-Merton" and "heteroskadasticity" are immediately loaded into memory; I tell recruiters I can do complex sorting algorithms: e.g. "bubble sort" in three different languages: Javascript, EcmaScript and ES16 - look how intelligent i am - and that will usually be enough to get me talking to someone else.
Success story sharing
:require => false
these particular gems and explicitlyrequire "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.require 'yaml'
, you now have theYAML
module as an object in memory.:require => false
and then in your code have arequire 'library_name_here'