Imagine a Rack application that, on startup, creates instances of some other Ruby applications and maps routes to those applications. This application has a Rack dependency of 1.2.2.
Now imagine we're developing a sub-application which will be run by this application. It has a Sinatra dependency of 1.2.6 and uses Bundler. It's gemfile is a barren:
source "http://rubygems.org"
gem "sinatra", "1.2.6"
Unfortunately, when we bundle install
this sub-application, Bundler, with no knowledge of the Rack 1.2.2 dependency of the parent application, will install the most recent version of Rack that is compatible with Sinatra 1.2.6: currently 1.3.2. Our Gemfile.lock will be:
GEM
remote: http://rubygems.org/
specs:
rack (1.3.2)
sinatra (1.2.6)
rack (~> 1.1)
tilt (< 2.0, >= 1.2.2)
tilt (1.3.2)
PLATFORMS
ruby
DEPENDENCIES
sinatra (= 1.2.6)
When we try to start the parent application (which starts our sub-application), we'll get:
You have already activated rack 1.2.2, but your Gemfile requires rack 1.3.2. Consider using bundle exec. (Gem::LoadError)
What is the correct way to handle this situation? Yes, we could explicitly require rack 1.2.2, but we'd effectively be stating a dependency of a dependency. I'd imagine that, ideally, the parent application would be a gem which our sub-application would require, but in this situation, we don't have the ability to make it so.
Your "main" process should use bundle exec
to launch the subprocesses, just as the error message recommends.
That will force the new app to launch within it's own Gemfile
's bundle context, not the global gem context. As a result, the new app will be launched using Rack 1.3.2 or later, not Rack 1.2.2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With