Index: rubygems.rb =================================================================== --- rubygems.rb (revision 6694) +++ rubygems.rb (revision 6697) @@ -8,6 +8,7 @@ require 'rubygems/rubygems_version' require 'rubygems/defaults' require 'thread' +require 'weakref' module Gem class LoadError < ::LoadError @@ -608,7 +609,14 @@ # Returns the Gem::SourceIndex of specifications that are in the Gem.path def self.source_index - @@source_index ||= SourceIndex.from_installed_gems + begin + raise WeakRef::RefError unless @@source_index + @@source_index.__getobj__ + rescue WeakRef::RefError + source_index = SourceIndex.from_installed_gems + @@source_index = WeakRef.new(source_index) + source_index + end end ## Index: rubygems/specification.rb =================================================================== --- rubygems/specification.rb (revision 6694) +++ rubygems/specification.rb (revision 6697) @@ -74,9 +74,6 @@ # ------------------------- Class variables. - # List of Specification instances. - @@list = [] - # Optional block used to gather newly defined instances. @@gather = nil @@ -123,11 +120,6 @@ # ------------------------- Infrastructure class methods. - # A list of Specification instances that have been defined in this Ruby instance. - def self.list - @@list - end - # Used to specify the name and default value of a specification # attribute. The side effects are: # * the name and default value are added to the @@attributes list @@ -534,7 +526,6 @@ assign_defaults @loaded = false @loaded_from = nil - @@list << self yield self if block_given? Index: rubygems/gem_path_searcher.rb =================================================================== --- rubygems/gem_path_searcher.rb (revision 6694) +++ rubygems/gem_path_searcher.rb (revision 6697) @@ -12,21 +12,6 @@ # class Gem::GemPathSearcher - # - # Initialise the data we need to make searches later. - # - def initialize - # We want a record of all the installed gemspecs, in the order - # we wish to examine them. - @gemspecs = init_gemspecs - # Map gem spec to glob of full require_path directories. - # Preparing this information may speed up searches later. - @lib_dirs = {} - @gemspecs.each do |spec| - @lib_dirs[spec.object_id] = lib_dirs_for(spec) - end - end - # # Look in all the installed gems until a matching _path_ is found. # Return the _gemspec_ of the gem where it was found. If no match @@ -48,27 +33,25 @@ # only that there is a match. # def find(path) - @gemspecs.each do |spec| - return spec if matching_file(spec, path) + gemspecs.detect do |spec| + matching_file(spec, path) end - nil end private # Attempts to find a matching path using the require_paths of the # given _spec_. - # - # Some of the intermediate results are cached in @lib_dirs for - # speed. def matching_file(spec, path) # :doc: - glob = File.join @lib_dirs[spec.object_id], "#{path}#{Gem.suffix_pattern}" - return true unless Dir[glob].select { |f| File.file?(f.untaint) }.empty? + glob = File.join lib_dirs_for(spec), "#{path}#{Gem.suffix_pattern}" + Dir[glob].detect do |file| + File.file?(file.untaint) + end end # Return a list of all installed gemspecs, sorted by alphabetical # order and in reverse version order. - def init_gemspecs + def gemspecs Gem.source_index.map { |_, spec| spec }.sort { |a,b| (a.name <=> b.name).nonzero? || (b.version <=> a.version) }