0

I try to upgrade a legacy application from Ruby 1.8.7 to 2.2.3. Afterwards the rendering of builder templates raises errors about unknown classes.

uninitialized constant Builder::XmlMarkup::BigDecimal (NameError)

It seem that within the Builder::XmlMarkup constants like classes disappear.

### example.xml.builder (template) ###
BigDecimal.new('23') # no error

class << xml
  def some
    data(BigDecimal.new('23')) # raises an error in 2.2.3
  end
end

xml.test { xml.some }

### main script ###
require 'rubygems'
require 'builder'
require 'bigdecimal'

def eval_script(file)
  xml = Builder::XmlMarkup.new
  binding.eval(File.read(file), file)
  xml.target!
end

template = File.join(File.dirname(__FILE__), 'example.xml.builder')
puts eval_script(template)
# Ruby 1.8.7 / builder 3.2.0 => <test><data>0.23E2</data></test>
# Ruby 2.2.3 / builder 3.2.2 => ./eval_script.rb:5:in `some': uninitialized constant Builder::XmlMarkup::BigDecimal (NameError)

I found no reason for the behavior. How can I fix the problem?

BTW: I have the same problem with the method lookup, e.g format('%d', 42) which returns the full XML document but doesn't call Kernel.format in Ruby 2.2.3.

sschmeck
  • 7,233
  • 4
  • 40
  • 67

1 Answers1

0

I found a workaround overriding const_missing which has to be applied to every template file. It works so far for the legacy application.

### example.xml.builder (template) ###
class << xml
  def self.const_missing(name)
    super rescue ::Object.const_get(name)
  end

  def some
    data(BigDecimal.new('23'))
  end
end

xml.test { xml.some }

But every time the constant BigDecimal is used, it triggers const_missing and then raises a NameError and calls the Object method.

sschmeck
  • 7,233
  • 4
  • 40
  • 67