Why do you need require 'bundler/setup' ?
It ensures you're loading Gemfile defined gems. Please have a look at the documentation here https://bundler.io/v1.12/bundler_setup.html
What do require 'bundler/setup' and 'Bundler.require' do?
What require 'bundler/setup'
does is make Rails automatically discover the Gemfile and then add all the gems defined in it to Ruby's load path.
Bundler.require(:default, Rails.env)
will then require all the gems in the Gemfile depending on the current Rails environment. So if current environment is the development environment, Rails will load all gems that are meant to be used in the development environment.
Hope that helps!
Difference between 'require bundler' and 'require bundler/setup'
When referring to gems, require 'foo'
would require the foo.rb
file that is located in the gem's lib
directory. That file usually has the same name as the gem and is responsible for requiring all other necessary files for the gem to function.
When you do require 'foo/bar'
, you search for lib/foo/bar.rb
. In other words, you require only a specific file from that gem and not the whole thing.
The bundler/setup
is responsible for loading all gems described in your Gemfile. Bundler.with_clean_env
is a completely different functionality, defined in the gem's main file.
what's the difference between bundle.setup and bundle.require
Bundler.setup
modifies the LOAD_PATH, so you can do things like require 'some_gem'
and they will work. It allows you to require gems 'by hand'. Before Bundler, using Rubygems, you would achieve much of the same effect doing require 'rubygems'
.
Bundler.require(:default)
on the other hand actually requires all the gems in the Gemfile (assuming you're not using groups; otherwise it requires those in the specified groups if you provide arguments). It is a shorthand for a bunch of require 'some_gem'
statements.
See http://gembundler.com/rationale.html. Note that they say you have to do require 'bundler/setup'
before doing Bundler.require
, but in practice this usually is not necessary. I almost never use Bundler.setup
(or require 'bundler/setup
), because I require all gems via Bundler.require
).
Bundler difference between setup and require?
Google can be your friend. Read this and this.
TL;DR Use Bundler.require instead of Bundler.setup
Are bundle exec and require 'bundler/setup' equivalent?
In your specific example they can be considered the same, however in reality they are not the same.
bundle exec
makes some changes to the environment that bundler/setup
does not make. If your foo.rb
never runs a subshell, or never tries to run other ruby executables in subshells, then both versions are equivalent (they will both load bundled gems correctly and work exactly the same).
The whole idea with bundle exec
is to enable you to run executables that were not originally designed with bundler in mind. Like rspec
, rails
, rackup
. If your own app (foo.rb
) does not try to run such executables that might be dependent on your bundles, then it makes no difference either way. Since all you want to make sure with bundler is that you load the correct gems, and for that bundler/setup
works exactly as expected in your case.
From the bundler docs when talking about running ruby system executables:
In some cases, running executables without bundle exec may work, if the executable happens to be installed in your system and does not pull in any gems that conflict with your bundle.
However, this is unreliable and is the source of considerable pain. Even if it looks like it works, it may not work in the future or on another machine.
Then from the manpage of bundle exec you can get some additional clues as to what bundle exec
actually does:
ENVIRONMENT MODIFICATIONS
- make sure that it's still possible to shell out to bundle from inside a command invoked by bundle exec (using $BUNDLE_BIN_PATH)
- put the directory containing executables (like rails, rspec, rackup) for your bundle on $PATH
- make sure that if bundler is invoked in the subshell, it uses the same Gemfile (by setting BUNDLE_GEMFILE)
- add -rbundler/setup to $RUBYOPT, which makes sure that Ruby programs invoked in the subshell can see the gems in the bundle
So if you build your app with bundler support in mind, then you never need to bundle exec
your app.
But if you need to use other tools that load your app code that might load gems before they load your app code (which then might pull in a wrong non-bundled gem), then you need to use bundle exec
.
Bundler: why does it read the gemspec on require bundler/setup ?
Whenever you run bundler, it has to parse the Gemfile to actually figure out what gems need to be loaded, what has to be added to $LOAD_PATH
and so on. As part of that, it has to parse gemspec
.
The Gemfile.lock contains info on all of the gems as well as the dependencies to save startup time, but it doesn't alleviate the need for it to parse the Gemfile.
There are various ways you could work around it. Two simple ones would be to use File.read
and some regex to pull out the version. Or require the gem_name.rb and gem_name/version.rb files.
Related Topics
How to Split String into Only Two Parts with a Given Character in Ruby
Why Is Ruby's Date Class Automatically Loaded But Datetime Is Not
What Is a Worker in Ruby/Rails
How to Force One Field in Ruby's CSV Output to Be Wrapped with Double-Quotes
How to Safely Join Relative Url Segments
Rails 4.1 Mailer Previews and Devise Custom Emails
Do Ruby 1.8 and 1.9 Have the Same Hash Code for a String
Ruby: Write Escaped String to Yaml
Vi Input Mode in Command Line Matlab
Differencebetween "Be_True" and "Be True" in Rspec
Rails: How to Get a File Extension/Postfix Based on the Mime Type
How to Add Child Nodes in Nodeset Using Nokogiri
How Does MACports Install Packages? How to Activate a Ruby Installation Done via MACports
Escape Double and Single Backslashes in a String in Ruby
What Happens When Modifying Gemfile.Lock Directly
Sinatra with a Persistent Variable
How to Access Firefox Extension I Added in Selenium Webdriver
Are Ruby 1.9 Regular Expressions Equally Powerful to a Context Free Grammar