Question

'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?

Was it helpful?

Solution

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?

OTHER TIPS

I built and published my first gem on Rubygems following this links:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top