I'm using a gem that comes with my program, and I simply do
Gem.path.insert(0, basedir + '/packages/lib')
and it works (basedir is set already). Now this works with the older ruby we have (ruby 2.0.0p247 on rhel5, not in /usr/bin).
We have other machines with rhel7 where /usr/bin/ruby is ruby 2.0.0p353, and there the same code does not work - some gems fail to be required.
There (and on the old machs as well)
ENV['GEM_HOME'] = basedir + '/packages/lib'
Gem.clear_paths
works, but this is totally ugly.
Why doesn't the Gem.path.insert work here, and what would be portable?
(Neither GEM_PATH nor GEM_HOME are set.)
You should use Gem.paths=. It calls Gem.clear_paths for you and initializes the needed variables.
Gem.paths = {
'GEM_HOME' => '/opt/rubygems/ruby',
'GEM_PATH' => '/opt/rubygems/ruby:/opt/rubygems/2.0'
}
# for your example
Gem.paths = { 'GEM_HOME' => "#{basedir}/packages/lib" }
If you only need one Gem or a Ruby library that is not shipped as a Gem, then just include it's lib folder to $LOAD_PATH.
$LOAD_PATH << '/opt/rubygems/ruby/gems/name-0.1.2/lib'
# for your example
$LOAD_PATH.unshift "#{basedir}/packages/lib"
A workaround for you would be the following, but I recommend setting Gem.paths or adding to $LOAD_PATH.
Gem.path.insert(0, basedir + '/packages/lib')
Gem::Specification.dirs << "#{basedir}/packages/lib/specifications'
I have tested Gem.path.insert with ruby-2.0.0p247, ruby-2.0.0p353 (both self compiled) and ruby-2.0.0p353 (CentOS RPM 2.0.0.353-20.el7). The self compiled and Ruby 2.1.3p242 from openSUSE 13.2 works. The CentOS Ruby doesn't work for me eather, because it calls Gem::Specification.dirs before the interpreter reaches the Gem.path.insert line. Don't know why the CentOS and RHEL RPMs behaves different from a clean build or openSUSE RPMs.
ruby compiled from source calls:
--------------------------------
Gem.clear_paths
ruby from CentOS7 calls:
-----------------
Gem.clear_paths
Gem::Specification.dirs
Gem.path
Gem.paths
The following is a list of what gets called on a require.
require calls Gem::Specification.dirsGem::Specification.dirs calls Gem.path to set it's @@dirs, because it isn't initialized at first callGem.path calls Gem.paths.pathGem.paths sets it's @path to Gem::PathSupport.new, because it isn't initialized at first callSo, if Gem::Specification.dirs is called before the custom path is inserted to Gem.path, the Rubygem library doesn't know to look at the custom folder's specifications path.
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