Standard Library vs. 3rd Party Library

Loading rdoc in a ruby script leads to a conundrum of sorts.

require ‘rdoc/rdoc’

This will load the version of RDoc distributed with Ruby. But it is a
very old version. Installing the latest version of RDoc via gem
however doesn’t help either. It still loads Ruby’s distributed version
b/c RubyGems lets Ruby try to load a lib first, and only looks for it
in the installed gems if that fails. Thus the only way to get the
latest version of RDoc is to use.

require ‘rubygems’
gem ‘rdoc’

But as we all know that is not a good practice --in the advent that
another load system is being used. I work around it with some error
caching code, of course, But that doesn’t answer the open issue that
3rd party libraries distributed with Ruby can fail to load properly if
a later version is installed via another means such as RubyGems.

My first thought for a solution is that RubyGems should search for the
file first, rather then let Ruby try and fail before doing so. And I
think Ruby 1.9 basically does exactly that by by putting all the
latest gems automatically put on the load path (although I here there
is an issue with this as well at
GitHub - wycats/rubygems-bug-demo).
However, this is very inefficient. Consider loading ‘ostruct.rb’ –
does it really need to search through every installed gem first before
finally picking ostruct.rb up from Ruby itself?

So I’m a starting to think that Ruby could use a distinction between
standard libs and redistributed libs, and provide a way to look them
up separately. This way RubyGems could set things up to search Ruby’s
standard libs first, then the gems, then Ruby’s redistributed libs.

Thomas S. wrote:

Thus the only way to get the
latest version of RDoc is to use.

require ‘rubygems’
gem ‘rdoc’

I have the same problem with soap4r. To avoid the crufty version
supplied with Ruby:

require ‘rubygems’
gem ‘soap4r’

I don’t have a particularly good solution for this, except to localise
this code to the startup script:

[bin/myapp]
#!/usr/bin/ruby
require ‘rubygems’
gem ‘soap4r’,’>= 1.5.8’
$:.unshift File.join(File.dirname(FILE),’…’,‘lib’)
require ‘myapp’
MyApp.run

It’s ugly, but at least it’s only in one place. Should anyone need to
run your code with a non-rubygems framework, they can make a new startup
script.

Also, I don’t know if there’s a way to test if rubygems is present, but
at worst you could do:

begin
gem ‘soap4r’
rescue NoMethodError
end