[BUG] RubyGems: "No such file to load -- rubygems/builder"

I added some debug information to the require method as defined
by RubyGems, because I didn't trust a message I got ("No such
file to load -- rubygems/builder").

The problem occurs when require is invoked recursively. In the
situation that a LoadError is thrown some levels deep, the file
it complains about ("rubygems/builder") isn't the file that
raised the exception ("yaml", because it's the first "9"-line).
After installing "libyaml-ruby", I got one step further: "zlib"
is missing", and so on. But in all situations, I got the same
message ("No such file to load -- rubygems/builder").

Looks like a bug...

gegroet,
Erik V.

···

----------------------------------------------------------------

   def require(path)
p [1, path]
     require__ path
p [2, path]
   rescue LoadError
p [3, path]
     begin
p [4, path]
       @gempath_searcher ||= Gem::GemPathSearcher.new
p [5, path]
       if spec = @gempath_searcher.find(path)
p [6, path]
         Gem.activate(spec.name, true, "= #{spec.version}")
p [7, path]
         require__ path
p [8, path]
       else
p [9, path]
         raise LoadError, "No such file to load -- #{path}"
       end
     end
   end
end # module Kernel

----------------------------------------------------------------

erik@erikshost:~$ gem install sqlite-ruby
[1, "rubygems/user_interaction"]
[2, "rubygems/user_interaction"]
[1, "rubygems/builder"]
[1, "rubygems/package"]
[1, "yaml"]
[3, "yaml"]
[4, "yaml"]
[5, "yaml"]
[9, "yaml"]
[3, "rubygems/package"]
[4, "rubygems/package"]
[5, "rubygems/package"]
[9, "rubygems/package"]
[3, "rubygems/builder"]
[4, "rubygems/builder"]
[5, "rubygems/builder"]
[9, "rubygems/builder"]
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:35:in
`require': No such file to load -- rubygems/builder (LoadError)
         from /usr/local/lib/site_ruby/1.8/rubygems.rb:58:in
`manage_gems'
         from /usr/local/bin/gem:4

----------------------------------------------------------------

This is a bug, and I'm not sure the best way to handle this -- but the
real problem is the way that Debian-family Linuxes package Ruby.

-austin

···

On Sat, 5 Feb 2005 03:40:15 +0900, Erik Veenstra <google@erikveen.dds.nl> wrote:

I added some debug information to the require method as defined
by RubyGems, because I didn't trust a message I got ("No such
file to load -- rubygems/builder").

The problem occurs when require is invoked recursively. In the
situation that a LoadError is thrown some levels deep, the file
it complains about ("rubygems/builder") isn't the file that
raised the exception ("yaml", because it's the first "9"-line).
After installing "libyaml-ruby", I got one step further: "zlib"
is missing", and so on. But in all situations, I got the same
message ("No such file to load -- rubygems/builder").

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Austin Ziegler <halostatue@gmail.com> writes:

This is a bug, and I'm not sure the best way to handle this -- but the
real problem is the way that Debian-family Linuxes package Ruby.

Progress is being made; people who are interested in affecting the
process or outcome should join the debian-ruby mailing list
(http://lists.debian.org/\), and read the archives, at least for
January.

-=Eric

···

--
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
    -- Blair Houghton.

> I added some debug information to the require method as
> defined by RubyGems, because I didn't trust a message I got
> ("No such file to load -- rubygems/builder").
>
> The problem occurs when require is invoked recursively. In
> the situation that a LoadError is thrown some levels deep,
> the file it complains about ("rubygems/builder") isn't the
> file that raised the exception ("yaml", because it's the
> first "9"-line). After installing "libyaml-ruby", I got one
> step further: "zlib" is missing", and so on. But in all
> situations, I got the same message ("No such file to load
> -- rubygems/builder").

This is a bug, and I'm not sure the best way to handle this
-- but the real problem is the way that Debian-family Linuxes
package Ruby.

I disagree. This example is a result of the strange Ruby
packages on Debian systems. That's true. But the same problem
can occur in other situations as well. The way the require
method of RubyGems catches the LoadError exception is the real
problem.

The solution is really easy... See below. You can use solution
B or C.

gegroet,
Erik V.

···

----------------------------------------------------------------

$ cat a.rb
class LoadError
end

module Kernel
   alias require__ require

   def require(path)
     require__ path
   rescue LoadError => e
     begin
       if false # No gem found.
       else
         #raise LoadError, "No such file to load -- #{path}" # A
         #raise e # B
         raise LoadError, e.message # C
       end
     end
   end
end

puts "A1"
require "b"
puts "A2"

$ cat b.rb
puts "B1"
require "c"
puts "B2"

$ cat c.rb
puts "C1"
require "d" # Doesn't exist.
puts "C2"

$ ruby a.rb
A1
B1
C1
a.rb:15:in `require': No such file to load -- d (LoadError)
         from a.rb:22

----------------------------------------------------------------

It's not the only one. Any time *anything* catches a LoadError, the
real exception can be hidden, which is why I said I'm not sure the
best way to handle this. I faced something similar to this in Ruwiki
(because I have a fairly sophisticated require technique to try to
discover things in various places since Ruwiki can be installed in
multiple fashions), and I'm not sure I'm happy with the result that
I managed there, either.

In part, one might argue that silently catching a LoadError is a bad
thing. In some testing code that I have for Text::Format, I do:

  begin
    require 'text/hyphen'
    hy = Text::Hyphen.new
  rescue LoadError
    begin
      require 'tex/hyphen'
      hy = TeX::Hyphen.new
    rescue LoadError
      print 'S'
      return true
    end
  end

This way, I can exercise the external interfacing of Text::Format
with one of the two available hyphenation libraries -- but I lie to
test/unit in order to do so, sort of. However, if the require of
text/hyphen failed for a reason *other* than text/hyphen not being
installed (e.g., text/hyphen required a library that it currently
doesn't but is broken because of Debian packaging decisions, for
example), this test program would hide that.

As I said, I'm not sure *how* it should deal with this. Perhaps a
variant of LoadError that chains the pieces together, e.g.,

  class GemLoadError < LoadError; end

and set it up to keep track of any other LoadError or GemLoadError
caught?

-austin

···

On Sat, 5 Feb 2005 06:20:15 +0900, Erik Veenstra <google@erikveen.dds.nl> wrote:

This is a bug, and I'm not sure the best way to handle this --
but the real problem is the way that Debian-family Linuxes
package Ruby.

I disagree. This example is a result of the strange Ruby packages
on Debian systems. That's true. But the same problem can occur in
other situations as well. The way the require method of RubyGems
catches the LoadError exception is the real problem.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca