From: Brian Candler Date: 2007-10-22T16:50:28+09:00 Subject: REXML (1.8.6-p110) backwards compatibility problem with rcov When I upgraded my Ubuntu 6.06.1 system from its stock ruby-1.8.4 to ruby-1.8.6-p110, I found that the previously working rcov-0.8.0.2 was raising REXML exceptions when it tried to generate its output (*) I needed to make a couple of patches to REXML to fix this. The first patch is because rcov passes Fixnums as attribute values, e.g. table_(:cellpadding => 0, :cellspacing => 0, :align => "right") This could have been fixed at the rcov side, but since it *did* used to work with rexml, I consider this a backwards-compatibility failure. The fix is trivial: --- rexml/text.rb.orig 2007-10-22 08:00:04.000000000 +0100 +++ rexml/text.rb 2007-10-22 08:00:33.000000000 +0100 @@ -286,7 +286,7 @@ EREFERENCE = /&(?!#{Entity::NAME};)/ # Escapes all possible entities def Text::normalize( input, doctype=nil, entity_filter=nil ) - copy = input + copy = input.to_s # Doing it like this rather than in a loop improves the speed #copy = copy.gsub( EREFERENCE, '&' ) copy = copy.gsub( "&", "&" ) (Note that there are other places in this file which might benefit from a to_s as well) The second is almost certainly a bug in REXML: it's a misnamed local variable. --- rexml/document.rb.orig 2007-10-22 08:02:36.000000000 +0100 +++ rexml/document.rb 2007-10-22 08:03:01.000000000 +0100 @@ -183,7 +183,7 @@ output = Output.new( output, xml_decl.encoding ) end formatter = if indent > -1 - if transitive + if trans REXML::Formatters::Transitive.new( indent, ie_hack ) else REXML::Formatters::Pretty.new( indent, ie_hack ) After these changes, rcov seems to run happily. I wasn't sure where best to post this problem and its solution: ruby-core (since REXML is in the ruby standard library), the REXML home site, or the rcov home site. So I'm posting it here instead :-) Regards, Brian. (*) The exception I saw initially was: /usr/local/lib/ruby/1.8/rexml/text.rb:292:in `normalize': private method `gsub' called for 0:Fixnum (NoMethodError) from /usr/local/lib/ruby/1.8/rexml/element.rb:1084:in `[]=' from /usr/local/lib/ruby/1.8/rexml/element.rb:586:in `add_attribute' from (eval):490:in `table_' from (eval):490:in `each' from (eval):490:in `table_' from (eval):490:in `each' from (eval):490:in `table_' from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:702:in `format_overview' ... 61 levels... After I fixed this by adding to_s in Text::normalize, I got /usr/local/lib/ruby/1.8/rexml/document.rb:186:in `write': undefined local variable or method `transitive' for ... :REXML::Document (NameError) from (eval):93:in `pretty' from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:727:in `format_overview' from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:758:in `create_index' from (eval):104:in `create' from (eval):80:in `tracking_additions' from (eval):103:in `create' from (eval):372:in `x_' from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:758:in `create_index' ... 21 levels...