问题
I have rails
(2.3.5) and prawn
(0.12.0) installed. When I install prawnto
, gem installs rails
version 3.2.6 also.
The dependency of prawnto
is:
prawn >= 0
rails >= 2.1
Why gem install Rails 3.x when the prawnto
dependency is already there?
回答1:
tl;dr Use Bundler. It rocks.
Alright, this is basically down to how dependency resolution works in RubyGems. If you're not terribly familiar with it, get up to speed real quick like with the Primer panel from this XKCD comic. RubyGems dependency management and the Primer storyline are very similar in terms of complexity.
When a gem specifies a dependency of, say rails >= 2.1
, when you go to install that gem, RubyGems conveniently ignores all the gems that you've currently got installed and then queries the web API to find the absolute latest version of Rails that's greater than or equal to 2.1
.
It will find, as of this writing, version 3.2.6
, and so will dutifully install that version of Rails because it fits the dependency requirements. It will also install every single dependency of Rails, and their dependencies, and the sub-sub-sub-sub-dependencies all the way down until there's not a gem left without a dependency installed.
I won't go into exactly how that works because it makes my vision go blurry when I think about it.
Now, if you were using something that's not pure-RubyGems such as Bundler, you'd be able to have a Gemfile like this:
source 'http://rubygems.org'
gem 'rails', '2.3.4'
gem 'prawnto', '0.1.1'
And then run bundle install
and then something magical will happen. Bundler will figure out the dependencies for all the gems specified in the Gemfile
, as well as the gems that they depend on, and then install only those gems.
This means that if you have prawnto
wanting Rails >= 2.1
, it won't install 3.2.6 because there's another dependency saying that Rails must precisely be 2.3.4
. So therefore Rails 2.3.4 will be installed.
If you have conflicting versions, with a gem A specifying a dependency on gem B of ~> 1.0
, but then gem C specifying a dependency that gem B must be '= 0.5.0', Bundler won't be very happy and will raise an error because the dependencies can't be resolved.
I'd really recommend using Bundler for all your Rails projects. Even those that are running on Rails 2. There's a page on the Bundler website which will get you started with a Rails 2.3 project and Bundler.
来源:https://stackoverflow.com/questions/11183509/why-prawnto-gem-installs-rails-3-x-when-there-is-already-a-rails-2-x