Reputation: 15276
This is more curiosity question and not a problem. When many version are present on the system which ones are chosen when require
command is used? Background of the story is: I was implementing bundler
gem in project (not Rails project). I had no issues but other developers had issues, after quick investigation I realized that I did not use
require "bundler/setup"
which basically loads up bundled gems. Quick fix, but it got me wondering how does ruby via rubygems decide which gems to use. Since code broke because Ruby application used older version of one of the gems, and not the newer one. Meaning it does not use the "newest" gems, so what is logic behind it?
UPDATE
To further explain this question let say you have gems foo-1.0.1
and foo-1.0.2
when you say, require 'foo'
how does ruby know which one to load?
Upvotes: 1
Views: 104
Reputation: 79723
In Ruby you require
a file rather than a gem. If that file isn’t found on the current load path, Rubygems will search the installed gems for a file with that name, and if it finds one the gem is activated (meaning that it gets added to the laod path) and the file is then required. Normally a gem will have a file with the same name in its lib
dir. Only one version of a gem can be activated.
The gem that gets activated is the latest version available that is compatible with any other activated gems. Normally this will just mean that the latest version installed wil be activated, but this might not be the case if you have already activated some gems which declare dependencies on earlier version of the gem you’re trying to activate.
For example, if you have foo-1.0.1
and foo-1.0.2
installed, then require 'foo'
(assuming they have a file named foo.rb
in their lib
dirs and no other gem does) will cause version 1.0.2 to be activated. However if you also have a gem bar
which has a dependency on 1.0.1
then calling require 'foo'
after bar
has been activated will cause 1.0.1 of foo
to be activated.
Futhermore, if you try to require them in the other order, require 'foo'; require 'bar';
then you will get something like
Gem::LoadError: Unable to activate bar-1, because foo-2 conflicts with foo (= 1)
Here you can’t activate bar
, which depends on version 1.0.1 of foo
because you have already activated version 1.0.2 of foo
.
Upvotes: 3
Reputation: 77778
Without Bundler, you have to specify each gem you want. e.g.,
require 'my_gem'
require 'my_other_gem'
However, Bundler can make this a bit easier for you using a Gemfile
If this is your Gemfile
gem 'my_gem'
gem 'my_other_gem'
Calling this will include all gems
require 'bundler/setup'
Upvotes: 0