Tumbling with Ryan
03 Sep 08

REXML wrapping and rcov

I recently ran in to some problems trying to get Rcov to run on a new code base I’m working with.  Admittedtly a few of the files are far longer that I’d like, but a standard xml library should deal with such things gracefully.  Unfortunately, REXML will throw all sorts of nastiness on pretty.rb:131.  The problem is that the wrap function: a) doesn’t handle a few corner cases when spaces show up in weird spots, and b) since its a tail-recursive function if the string is long enough the interpreter will throw a Stack-level too deep error.

Fortunately the corner cases can be dealt with and as we all know tail-recursion can be eliminated and converted to a loop quite easily.  The patch looks like this (I’ll try and package it up properly at some point as a patch to core):

      def wrap(string, width)
        out = nil
        # Recursively wrap string at width.
        while true
          return [out, string].compact.join("\n") if string.length <= width
          place = string.rindex(' ', width) # Position in string with last ' ' before cutoff
          start = 0
          if place.nil? || place == 0
            start = width
            place = width
          else
            start = place + 1
          end 
          out = [out, string[0,place]].compact.join("\n")
          string = string[start..-1]
        end
      end