'bundler', popular ruby gem manipulation tool, installs gems into same directory as normal gem
command. But application executed with bundle exec
will have access only to gems installed with bundler, not "system-wide" gems. How this is done technically? Does bundler monkey-patch require
, or some path manipulation, or what?

- 40,413
- 64
- 174
- 277
2 Answers
Bundler makes sure that Ruby can find all of the gems in the Gemfile (and all of their dependencies). It does by configuring the load path so all dependencies in your Gemfile can be required. this is done using following call:
Bundler.setup
ruby LOAD_PATH
is the list of places on filesystem where ruby will look for files, if you do a require. think of it similar to PATH
variable in Linux/Windows OS but for ruby.
to see this in action, run load_path as root user. I am doing this from my mac
$ sudo ruby -e 'p $LOAD_PATH'
["/Library/Ruby/Site/2.0.0", "/Library/Ruby/Site/2.0.0/x86_64-darwin13", "/Library/Ruby/Site/2.0.0/universal-darwin13", "/Library/Ruby/Site", "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/vendor_ruby/2.0.0", "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin13", "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/vendor_ruby/2.0.0/universal-darwin13", "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/vendor_ruby", "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0", "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/x86_64-darwin13", "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/universal-darwin13"]
now, run the same command from inside your rails app:
$ ruby -e 'p $LOAD_PATH' #paths on new rails 4.1 app
["/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/uglifier-2.5.0/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/turbolinks-2.2.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/extensions/x86_64-darwin-12/2.1.0-static/sqlite3-1.3.9", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/sqlite3-1.3.9/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/sdoc-0.4.0/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/sass-rails-4.0.3/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/sass-3.2.19/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/rdoc-4.1.1/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/rails-4.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/sprockets-rails-2.0.1/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/sprockets-2.11.0/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/tilt-1.4.1/lib", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/json-1.8.1/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/jquery-rails-3.1.0/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/jbuilder-1.5.3/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/hike-1.2.3/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/coffee-rails-4.0.1/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/railties-4.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/coffee-script-2.2.0/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/execjs-2.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/coffee-script-source-1.7.0/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/activerecord-4.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/arel-4.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/activerecord-deprecated_finders-1.0.3/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/activemodel-4.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/actionmailer-4.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/mail-2.5.4/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/treetop-1.4.15/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/polyglot-0.3.4/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/mime-types-1.25.1/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/actionpack-4.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/rack-test-0.6.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/rack-1.5.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/erubis-2.7.0/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/builder-3.1.4/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/activesupport-4.0.2/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/tzinfo-0.3.39/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/thread_safe-0.3.3/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/multi_json-1.10.0/lib", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/minitest-4.7.5/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/i18n-0.6.9/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1/gems/rake-10.3.1/lib", "/Users/gaurish/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.1/lib", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/site_ruby/2.1.0", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/site_ruby/2.1.0/x86_64-darwin12.0", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/site_ruby", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/vendor_ruby/2.1.0", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/vendor_ruby/2.1.0/x86_64-darwin12.0", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/vendor_ruby", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0", "/Users/gaurish/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/x86_64-darwin12.0"]
notice, how the load path has been modified to point exactly to the gem version specified in Gemfile
As you may notice bundler tweaks this load path, so it points to dependencies given in Gemfile. so whenever you run require
ruby will only pickup version given in LOAD PATH
and remember this load path is set/modified by bundler, during the Bundler.setup
call. so it can exactly point ruby to whatever file version it wishes as per the Gemfile as you can see from above example when we printed load path of our rails app vs outside the rails app as root user
Wondering it this answer your question?

- 33,537
- 28
- 98
- 137
-
This is only part of the answer. If Rubygems is loaded (which it is by default in current Ruby versions) then if you call `require` and the target isn’t found in the current load path your other gems are searched for a match. If one is found the matching gems lib dir is added to the load path. Bundler prevents this by [removing the patched `require` method that Rubygems adds](https://github.com/bundler/bundler/blob/v1.6.2/lib/bundler/rubygems_integration.rb#L214-224). – matt May 11 '14 at 16:15
I built and published my first gem on Rubygems following this links:
- Official Rubygems steps: http://guides.rubygems.org/
- Ruby : How to write a gem?