Reputation: 6764
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.)
Upvotes: 3
Views: 2675
Reputation: 1476
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.dirs
Gem::Specification.dirs
calls Gem.path
to set it's @@dirs
, because it isn't initialized at first callGem.path
calls Gem.paths.path
Gem.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.
Upvotes: 9