From: Erik Veenstra Date: 2008-08-01T22:54:10+09:00 Subject: About circular dependencies in RubyGems (the library). And about the order in $". ------=_Part_4219_6570385.1217598908478 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi, There's a circular dependency in RubyGems. I mean in the library itself, not in the collection of gems. Try this: $ RUBYOPT= ruby -e 'require "rubygems/exceptions"' /usr/local/lib/ruby/site_ruby/1.8/rubygems/remote_fetcher.rb:19: uninitialized constant Gem::Exception (NameError) from /usr/local/lib/ruby/site_ruby/1.8/rubygems/spec_fetcher.rb:4:in `require' from /usr/local/lib/ruby/site_ruby/1.8/rubygems/spec_fetcher.rb:4 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:10:in `require' from /usr/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:10 from /usr/local/lib/ruby/site_ruby/1.8/rubygems.rb:767:in `require' from /usr/local/lib/ruby/site_ruby/1.8/rubygems.rb:767 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/exceptions.rb:1:in `require' from /usr/local/lib/ruby/site_ruby/1.8/rubygems/exceptions.rb:1 from -e:1:in `require' from -e:1 The main script requires rubygems/exceptions.rb, which requires rubygems.rb, which requires rubygems/exceptions.rb (which is skipped since it has already been required (although is not yet listed in $"...)) and rubygems/source_index.rb, which requires rubygems/spec_fetcher.rb, which requires rubygems/remote_fetcher.rb, which defines class FetchError as a subclass of Gem::Exception, which fails since Gem::Exception has not yet been defined (rubygems/exceptions.rb is still on line 1). This causes RubyScript2Exe to fail. RubyScript2Exe sequentially requires every entry in $" when tracing the application. It's essentially doing this: $ export RUBYOPT= $ ruby -r $THE_LIBRARY -e 'puts $"' | xargs ruby -e 'ARGV.each{|x| puts x ; require x}' Which works for all libraries on my machine, except for RubyGems. The essence of the problem is a bit nasty: a library is only added to $" _after_ it's executed, so the order in which the libraries appear in $" is reversed. Well that's true for indirect dependencies (app requires a, which requires b, which requires c ==> $" == ["c.rb", "b.rb", "a.rb"], but not for sequential dependencies (app requires a, b and c ==> $" == ["a.rb", "b.rb", "c.rb"]). Question: Is it possible to investigate the exact order in which libraries are required correctly? Obviously $" won't work. We can't wrap Kernel#require either, since you'll miss the libraries which are required on the command line or in $RUBYOPT. Any ideas/suggestions/comments? Thanks. gegroet, Erik V. - http://www.erikveen.dds.nl/ ------=_Part_4219_6570385.1217598908478--