How does require rubygems help find rubygem files?
ruby, rubygems
Solution
Here's the current version of the relevant source: https://github.com/rubygems/rubygems/blob/02ead548e38ff90923444fa7c0ff9f6a5dbd87b0/lib/rubygems/custom_require.rb. (Edit: here's an earlier version (1.5.2) that more clearly expresses what happens.)
The docs say:
When RubyGems is required, `Kernel#require` is replaced with our own which is capable of loading gems on demand.
When you call `require 'x'`, this is what happens:
- If the file can be loaded from the existing Ruby loadpath, it is.
- Otherwise, installed gems are searched for a file that matches. If it's found in gem 'y', that gem is activated (added to the loadpath).
The normal `require` functionality of returning false if that file has already been loaded is preserved.
It does this by opening up `module Kernel` and aliasing the original require with `alias gem_original_require require`, then redefining `require` to first call the original version, and look at the gems if that doesn't work.
So the load path is only changed when you require a gem:
ruby-1.8.7-p330 :002 > $:.length
=> 9
ruby-1.8.7-p330 :003 > require 'rubygems'
=> true
ruby-1.8.7-p330 :004 > $:.length
=> 9
ruby-1.8.7-p330 :005 > require 'haml'
=> true
ruby-1.8.7-p330 :006 > $:.length
=> 10
Problem
While trying to solve Gem found in irb, not in Ruby , I tried seeing what effect `require 'rubygems'` had on my own installation: ``` $ irb irb(main):001:0> RUBY_VERSION => "1.8.7" irb(main):002:0> $: ["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/x86_64-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/x86_64-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/x86_64-linux", "."] => nil irb(main):003:0> require "rubygems" # Hasn't been required already => true irb(main):004:0> require "rubygems" # Will return false, because it's already been required => false irb(main):005:0> $: # Same as before => ["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/x86_64-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/x86_64-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/x86_64-linux", "."] ``` If requring rubygems doesn't modify `$:`, then how does it help find files? Does it monkeypatch `require`? If so, what variable does it use to find rubygem-installed libraries?