Bug fix for FastRI

I recently installed FastRI to speed up retrieving Ruby documentation. Following the directions on the website, I installed it from the source tarball rather than as a rubygem. Then, when I tried it, I received this error:

sbf5:~/fastri-0.3.1> qri
/usr/lib/ruby/1.8/rdoc/ri/ri_paths.rb:61: uninitialized constant Gem::Version (NameError)
from /usr/lib/ruby/1.8/rdoc/ri/ri_paths.rb:57:in `each'
from /usr/lib/ruby/1.8/rdoc/ri/ri_paths.rb:57
from /usr/local/lib/site_ruby/1.8/fastri/util.rb:38:in `require'
from /usr/local/lib/site_ruby/1.8/fastri/util.rb:38
from /usr/bin/qri:6:in `require'
from /usr/bin/qri:6

Here is what I found out, and how I fixed it.

Here is a snippet from the ri_paths.rb file that threw the error.

      require 'rubygems'
      ...
      all_paths.each do |dir|
          ...
          ver = Gem::Version.new version

The call to Gem::Version caused the exception, because it was undefined. However, rubygems.rb, which is required above, will on its own load the file rubygems/version.rb, which defines Gem::Version. So why was the constant missing when I ran FastRI?

The answer was in fastri/util.rb, which is used by FastRI:

# don't let rdoc/ri/ri_paths load rubygems.rb, that takes ~100ms !
emulation = $".all?{|x| /rubygems\.rb$/ !~ x} # 1.9 compatibility
$".unshift "rubygems.rb" if emulation
require 'rdoc/ri/ri_paths'
$".delete "rubygems.rb" if emulation

The highlighted line above fools Ruby into thinking that “rubygems.rb” has already been loaded. However, because of this, the Gem::Version remains unloaded.

One solution is to comment out the highlighted line, but as the comment above it says, this will slow down FastRI. Another solution is to explicitly require the necessary file to provide Gem::Version:

$".unshift "rubygems.rb" if emulation
require 'rubygems/version' if emulation # Fix a bug
require 'rdoc/ri/ri_paths'

This will provide the necessary class definition, thus fixing the bug.