A closer look at ruby gems

0

Have you ever been stuck at "Bulk updating Gem source index for http://gems.rubyforge.org/" while installing a gem?!  Due to a drop in the Internet connectivity in the Middle East and my own country, Egypt, installing gems started to be like hell - I had to wait for hours before having my library installed so I decided to have a closer look. Surprisingly, the problem was due to a bug in Rubygems 1.0.1.

You can easily overcome this by updating to the latest gem 1.3.1 through gem update --system

Gem downloads libraries metadata about all available gems in a gem server. By default, we have the gem source "http://gems.rubyforge.org/" and recently I added "http://gems.github.com". Gem saves this data in a cache file before it performs the required operation, so it doesn't have to download the data again the next time.

Part of the code that reads the cache looks like this:


MARSHAL_FIELDS = { -1 => 16, 1 => 16, 2 => 16 }
#...
# Load custom marshal format, re-initializing defaults as needed
def self._load(str)
   array = Marshal.load str

   spec = Gem::Specification.new
   spec.instance_variable_set :@specification_version, array[1]

   current_version = CURRENT_SPECIFICATION_VERSION

   field_count = MARSHAL_FIELDS[spec.specification_version]

   if field_count.nil? or array.size &lt field_count then
      raise TypeError, "invalid Gem::Specification format #{array.inspect}"
   end
...
end

That above load method is executed to load and validate the metadata of each library from the cache unless an exception is thrown. field_count represents the expected number of attributes per gem according the that gem specification version (either -1, 1, 2 but it is 16 in all cases). The keys of the MARSHAL_FIELDS hash are numbers, but the spec.specification_version is a string representation of that number. So MARSHAL_FIELDS[spec.specification_version] is always nil.

Changing it to MARSHAL_FIELDS[spec.specification_version.to_i] made the rubygems work like any civilized tool :).

 

Written By:

Mahmoud Said (blog.modsaid.com)
 

Post a Comment

eSpace podcast Prodcast

RSS iTunes