Ruby "gem generate" indexer broken with XML Builder 3.0.0

In which rubygems breaks compatibility, botches documentation, and fails to require specific gem versions.

The ruby "gem generate" command has a problem with the new XML Builder 3.0.0 gem. == Symptom: gem generate fails because it's missing XML Builder $ gem generate ERROR: While executing gem ... (RuntimeError) Gem::Indexer requires that the XML Builder library be installed: gem install builder We try this: $ gem install builder We verify that builder is now installed: $ gem list builder builder (3.0.0) But gem generate still fails with the same error message. How is this possible? == Invesigation: indexer needs builder/xchar and to_xs method Digging into rubygem source code, we find the error message come from in this file: /rubygems/indexer.rb The indexer initialize method tests for the XChar to_xs method: def initialize(directory) unless ''.respond_to? :to_xs then fail "Gem::Indexer requires that the XML Builder library be installed:" \ The indexer requires the Builder XChar library so it should work: gem 'builder' require 'builder/xchar' So we dig into the Builder source code... == How Builder does encoding and monkey patching

Builder does define the to_xs method, but only some of the time.

Builder does conditional definition of a big chunk of code: if String.method_defined?(:encode) ... new approach using encoding ... else ... old approach using monkey patching ... class String ... def to_xs(escape=true)

Essentially, Builder wants to define methods in terms of string encoding, but will fall back to monkey-patching the Ruby String class to define to_xs.

We look through the commits to Builder and we see that an older version of Builder does things differently: it always monkey-patches String and always defines to_xs. == Solution: Edit Ruby gem to require the older Builder We edit the Ruby gem source code to make it require the older Builder: gem 'builder', '~> 2.1' require 'builder/xchar' Success! $ gem generate Loading 50 gems from ... Loaded all gems Moral of the story: don't trust Ruby gem error messages, be on the lookout for incompatibilities due to gem versions, and if you are a gem author then please require gems with version numbers.

What's Next?

blog comments powered by Disqus