Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Remove the claim of 1.9.2 compatibility from guides.

#5985

In a hope that Rails 3.0.0 (or master) works well with Ruby 1.9.2, we changed our production environment to use Ruby 1.9.2. We found out that it's not true that Rails works well on 1.9.2, because of dependency on official builder gem (~> 2.1.2).

ruby-1.9.2-p0 > xml = Builder::XmlMarkup.new
NameError: uninitialized constant Builder::XmlBase::Symbol

    from /Users/skrat/.rvm/gems/ruby-1.9.2-p0/gems/builder-2.1.2/lib/builder/xmlbase.rb:40:in `method_missing'
    from /Users/skrat/.rvm/gems/ruby-1.9.2-p0/bundler/gems/rails-8124b2bc24b8/railties/lib/rails/commands/console.rb:44:in `start'

...

So the official builder gem, and it's github repo. is not 1.9.2 compatible. There is however a trivial fix to this issues, but it's being ignored by Jim Weirich, maintainer of builder. What I did is forking his repo, apply this trivial fix, add gemspec (for bundler compatibility), and use this repo, all to find out that it's still no-go because of:

Bundler could not find compatible versions for gem "builder":
In Gemfile: rails depends on

  builder (~> 2.1.2)
builder (2.2.0)

Reported by Dusan Maliarik · November 16th, 2010 @ 03:16 PM

State: invalid
Milestone: 3.x
Assigned to: José Valim José Valim
Importance: Low

Activity

  1. Aaron Patterson
    Aaron Patterson
    • Importance changed from to Low

    FUD?

    November 16th, 2010 @ 11:58 PM

  2. Santiago Pastorino
    Santiago Pastorino
    • State changed from new to invalid

    Dusan builder works ok for me in 1.9.2

    $ irb             
    ruby-1.9.2-p0 > require 'builder'
     => true 
    ruby-1.9.2-p0 > xml = Builder::XmlMarkup.new
     => #<Builder::XmlMarkup:0x0000010083b318 @indent=0, @level=0, @target="">
    

    November 17th, 2010 @ 12:01 AM

  3. Dusan Maliarik
    Dusan Maliarik

    Hi Santiago, it seems I'm not alone http://isitruby19.com/builder, this is a rather weird error likely to be caused by MRI Ruby. I haven't found any other way to get rid of it then use patched builder. I'm experiencing this with both Debian server and OS X desktop with freshly installed RFM and Ruby 1.9.2-p0.

    November 17th, 2010 @ 12:09 AM

  4. José Valim
    José Valim

    Dusan, can you point us to your fix and give us a link where Jim refuses to fix the issue? Maybe we can convince him over it. Thanks.

    November 17th, 2010 @ 08:59 AM

  5. Aditya Sanghi
    Aditya Sanghi

    I'm not able to reproduce this on OSX/1.9.2-p0 or on Ubuntu8.04/1.9.2-p0. I'm using rvm.

    test was the same as Santiago's above.

    Dusan, this obviously doesnt mean that this problem doesnt exist, but we need to determine the difference in the environments.

    November 17th, 2010 @ 09:51 AM

  6. Dusan Maliarik
    Dusan Maliarik

    Jose: by refusing, I mean ignoring (http://goo.gl/MQNtV)
    Aditya: the difference is that I'm not running my snippet in plain irb, but in Rails console.

    Personally, it doesn't make any sense to me, that code in builder is perfectly fine.

    November 17th, 2010 @ 10:13 AM

  7. José Valim
    José Valim

    Dusan, unless I am missing something, that ticket was opened less than 24h ago. I think that is a little bit too soon to express that he's ignoring it, no?

    And people trying to reproduce the error, please try to reproduce the error inside a rails console than just irb. This is because Rails tweaks constant lookups a bit.

    November 17th, 2010 @ 10:30 AM

  8. Dusan Maliarik
    Dusan Maliarik

    You're right, I totally missed the timestamp on that issue, my bad. In fact I don't know how does it behave in plain irb. I've seen this error in Rails logs and Rails console.

    November 17th, 2010 @ 10:49 AM

  9. José Valim
    José Valim
    • State changed from invalid to open
    • Milestone set to 3.x
    • Assigned user set to José Valim

    I also don't think 1.9.2 support should be removed from guides. We have bugs in different Ruby versions, nothing is perfect.

    Finally, we don't say it is "1.9.2 ready" to fool people and we would be happy if people contribute back reporting bugs and sending fixes when possible. More patience and comprehension is always welcome.

    November 17th, 2010 @ 10:59 AM

  10. Andrés Mejía
    Andrés Mejía

    Couldn't reproduce this on Rails 3.0.1 with Ruby 1.9.2-p0:

    $ rails c
    Loading development environment (Rails 3.0.1)
    ruby-1.9.2-p0 > require 'builder'
     => nil 
    ruby-1.9.2-p0 > xml = Builder::XmlMarkup.new
     => #<Builder::XmlMarkup:0x00000103328b20 @indent=0, @level=0, @target=""> 
    ruby-1.9.2-p0 >
    

    November 17th, 2010 @ 11:06 AM

  11. Aditya Sanghi
    Aditya Sanghi
    • State changed from open to invalid
    • Milestone cleared.
    • Assigned user cleared.

    On my OS X laptop -

    
    [ 04:22:07 ] > rails c production
    Loading production environment (Rails 3.0.3)
    >> RUBY_VERSION
    => "1.9.2"
    >> Rails.version
    => "3.0.3"
    >> require 'builder'
    => true
    >> xml = Builder::XmlMarkup.new
    => #<Builder::XmlMarkup:0x00000101cafda8 @indent=0, @level=0, @target="">
    
    [ 04:23:39 ] > ruby -v
    ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
    
    [ 04:23:42 ] > gem list builder
    
    *** LOCAL GEMS ***
    
    builder (2.1.2)
    
    [ 04:24:12 ] > bundle show builder
    /Users/adityasanghi/.rvm/gems/ruby-1.9.2-p0/gems/builder-2.1.2
    

    and on ubuntu

    asanghi@Risingsun10:~/tmp/btest$ rails c production
    Loading production environment (Rails 3.0.3)
    ruby-1.9.2-head > RUBY_VERSION
     => "1.9.2" 
    ruby-1.9.2-head > Rails.version
     => "3.0.3" 
    ruby-1.9.2-head > require 'builder'
     => true 
    ruby-1.9.2-head > Builder
     => Builder 
    ruby-1.9.2-head > xml = Builder::XmlMarkup.new
     => #<Builder::XmlMarkup:0x00000002827308 @indent=0, @level=0, @target=""> 
    ruby-1.9.2-head > exit
    asanghi@Risingsun10:~/tmp/btest$ ruby -v
    ruby 1.9.2p42 (2010-11-15 revision 29797) [x86_64-linux]
    asanghi@Risingsun10:~/tmp/btest$ uname -a
    Linux Risingsun10 2.6.24-24-server #1 SMP Fri Sep 18 16:47:05 UTC 2009 x86_64 GNU/Linux
    asanghi@Risingsun10:~/tmp/btest$ cat /etc/lsb-release 
    DISTRIB_ID=Ubuntu
    DISTRIB_RELEASE=8.04
    DISTRIB_CODENAME=hardy
    DISTRIB_DESCRIPTION="Ubuntu 8.04.4 LTS"
    asanghi@Risingsun10:~/tmp/btest$ gem list builder rails
    
    *** LOCAL GEMS ***
    
    builder (2.1.2)
    

    November 17th, 2010 @ 11:07 AM

  12. Aditya Sanghi
    Aditya Sanghi
    • State changed from invalid to open
    • Milestone set to 3.x
    • Assigned user set to José Valim

    Sorry there were updates while i had this page open. reverting ticket state back.

    November 17th, 2010 @ 11:08 AM

  13. Dusan Maliarik
    Dusan Maliarik

    I tried again with both 3.0.2 and edge Rails, and I don't see the bug anymore. Putting this into my "Strange Ruby issues resolved without intervention" bucket.

    November 17th, 2010 @ 03:08 PM

  14. José Valim
    José Valim
    • State changed from open to invalid

    November 17th, 2010 @ 03:22 PM

  15. Dusan Maliarik
    Dusan Maliarik

    Jim just applied mysterious ::Symbol fix and bumped version to 3.0.0, would it be possible to use this one? Colleague of mine is still experiencing this issue and we couldn't find an explanation for it so far :(

    November 18th, 2010 @ 12:20 PM

  16. Valentine Bichkovsky
    Valentine Bichkovsky

    What I've found so far.
    Clean Rails 3.0.3 install with Ruby 1.9.2-p0 (using RVM) works fine:

    rails c
    require 'builder'; Builder::XmlMarkup.new
    => #<Builder::XmlMarkup:0x0000000229fa70 @indent=0, @level=0, @target="">

    The problem occurs when you add "amqp" gem to the Gemfile (https://github.com/tmm1/amqp)

    .... gem "amqp"
    ...


    bundle install
    rails c
    require 'builder'; Builder::XmlMarkup.new
    NameError: uninitialized constant Builder::XmlBase::Symbol

    {mkd-extraction-f45ad5fc1bccc23b07b426430f1fdbad}


    The problem is caused by this line in xmlbase.rb:

    sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)

    which is fixed in Builder 3.0.0.

    How do I deal with this problem now:
    - add #{myapp}/lib dir to autorequire - clone Builder 3.0.0 from the repository
    mkdir #{myapp}/lib/builder
    cd #{cloned_builder_dir}/lib/bulder
    cp blankslate.rb css.rb xchar.rb xmlbase.rb xmlmarkup.rb #{myapp}/lib/builder

    Everything works fine now :)

    November 18th, 2010 @ 01:00 PM

  17. Valentine Bichkovsky
  18. Santiago Pastorino
    Santiago Pastorino

    I've bumped up the builder version

    November 18th, 2010 @ 02:58 PM

  19. Aditya Sanghi
    Aditya Sanghi

    @Dusan,

    Can you please list the gems you have in your application? From @valentine's comment above it seems amqp can trigger this problem, but there maybe others too that cause this problem. If we know which ones cause it, it will help those who are currently wondering about the failure relating to builder.

    @santiago, we should possibly mark this ticket resolved instead of invalid now that you've updated builder version. ya?

    Cheers,
    Aditya

    November 19th, 2010 @ 10:47 AM

  20. Santiago Pastorino
    Santiago Pastorino

    Aditya go ahead if you want ;)

    November 19th, 2010 @ 04:13 PM

  21. johnae
    johnae

    I've seen this error when using Rails, the amqp gem and ruby 1.9.2 together. The problem comes from a change in ruby 1.9.x. Basically, builder 2.1.2 and amqp (I guess, among other things) are unusable together. Builder 3.0.x does not have this problem it seems. Unfortunately Rails 3.0.x together with lots of other gems depend on builder 2.1.2.

    Please see:
    https://github.com/ruby-amqp/amqp/issues/#issue/38
    https://github.com/jimweirich/builder/issues/#issue/4

    March 17th, 2011 @ 04:06 PM

  22. johnae
    johnae

    An example of this behavior, this code works:

    require 'rubygems'
    #require 'mq'
    require 'rails'
    require 'builder'
    
    builder = Builder::XmlMarkup.new
    xml = builder.person { |b| b.name("Jim"); b.phone("555-1234") }
    puts xml
    

    this code doesn't:

    require 'rubygems'
    require 'mq'
    require 'rails'
    require 'builder'
    
    builder = Builder::XmlMarkup.new
    xml = builder.person { |b| b.name("Jim"); b.phone("555-1234") }
    puts xml
    

    March 17th, 2011 @ 04:08 PM

  23. johnae
    johnae

    In Rails master it seems to depend on builder 3.0.0 but in Rails release 3.0.5 (latest) it depends on builder 2.1.2. Don't know why that is.

    March 17th, 2011 @ 04:15 PM

  24. Dusan Maliarik
    Dusan Maliarik

    that seems like waiting for a release should do the trick, although, I've seen this problem, it wen't away after some time, and I don't remember what we did, we now use 3.0.3 with amqp without (builder related) issues

    March 17th, 2011 @ 04:18 PM

  25. johnae
    johnae

    This is what I've done in a monkey-patch - don't even remember exactly what did the trick anymore (been using it on occasion when this problem manifests):

    module Builder
    
      class CSS < BlankSlate
    
        def id!(arg, &block)
          _start_container('#'+arg.to_s, nil, ::Kernel.block_given?)
          _css_block(block) if block
          _unify_block
          self
        end
    
        def class!(arg, &block)
          _start_container('.'+arg.to_s, nil, ::Kernel.block_given?)
          _css_block(block) if block
          _unify_block
          self
        end
    
        def method_missing(sym, *args, &block)
          sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
          if block
            _start_container(sym, args.first)
            _css_block(block)
            _unify_block
          elsif @in_block
            _indent
            _css_line(sym, *args)
            _newline
            return self
          else
            _start_container(sym, args.first, false)
            _unify_block
          end
          self
        end
    
      end
    
      class XmlBase < BlankSlate
    
        def method_missing(sym, *args, &block)
          text = nil
          attrs = nil
          sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
          args.each do |arg|
            case arg
            when ::Hash
              attrs ||= {}
              attrs.merge!(arg)
            else
              text ||= ''
              text << arg.to_s
            end
          end
          if block
            unless text.nil?
              ::Kernel::raise ::ArgumentError,
                "XmlMarkup cannot mix a text argument with a block"
            end
            _indent
            _start_tag(sym, attrs)
            _newline
            begin
              _nested_structures(block)
            ensure
              _indent
              _end_tag(sym)
              _newline
            end
          elsif text.nil?
            _indent
            _start_tag(sym, attrs, true)
            _newline
          else
            _indent
            _start_tag(sym, attrs)
            text! text
            _end_tag(sym)
            _newline
          end
          @target
        end
    
      end
    
      class XmlMarkup < XmlBase
          def initialize(options={})
            indent = options[:indent] || 0
            margin = options[:margin] || 0
            super(indent, margin)
            @target = options[:target] || ""
          end
    
          def target!
            @target
          end
    
          def comment!(comment_text)
            _ensure_no_block ::Kernel::block_given?
            _special("<!-- ", " -->", comment_text, nil)
          end
    
          def declare!(inst, *args, &block)
            _indent
            @target << "<!#{inst}"
            args.each do |arg|
              case arg
              when ::String
                @target << %{ "#{arg}"} # " WART
              when ::Symbol
                @target << " #{arg}"
              end
            end
            if ::Kernel::block_given?
              @target << " ["
              _newline
              _nested_structures(block)
              @target << "]"
            end
            @target << ">"
            _newline
          end
    
          def instruct!(directive_tag=:xml, attrs={})
            _ensure_no_block ::Kernel::block_given?
            if directive_tag == :xml
              a = { :version=>"1.0", :encoding=>"UTF-8" }
              attrs = a.merge attrs
        @encoding = attrs[:encoding].downcase
            end
            _special(
              "<?#{directive_tag}",
              "?>",
              nil,
              attrs,
              [:version, :encoding, :standalone])
          end
    
          def cdata!(text)
            _ensure_no_block ::Kernel::block_given?
            _special("<![CDATA[", "]]>", text, nil)
          end
    
          private
    
          def _text(text)
            @target << text
          end
    
          # Insert special instruction. 
          def _special(open, close, data=nil, attrs=nil, order=[])
            _indent
            @target << open
            @target << data if data
            _insert_attributes(attrs, order) if attrs
            @target << close
            _newline
          end
    
          # Start an XML tag.  If <tt>end_too</tt> is true, then the start
          # tag is also the end tag (e.g.  <br/>
          def _start_tag(sym, attrs, end_too=false)
            @target << "<#{sym}"
            _insert_attributes(attrs)
            @target << "/" if end_too
            @target << ">"
          end
    
          # Insert an ending tag.
          def _end_tag(sym)
            @target << "</#{sym}>"
          end
    
          # Insert the attributes (given in the hash).
          def _insert_attributes(attrs, order=[])
            return if attrs.nil?
            order.each do |k|
              v = attrs[k]
              @target << %{ #{k}="#{_attr_value(v)}"} if v # " WART
            end
            attrs.each do |k, v|
              @target << %{ #{k}="#{_attr_value(v)}"} unless order.member?(k) # " WART
            end
          end
    
          def _attr_value(value)
            case value
            when ::Symbol
              value.to_s
            else
              _escape_quote(value.to_s)
            end
          end
    
          def _ensure_no_block(got_block)
            if got_block
              ::Kernel::raise IllegalBlockError.new(
                "Blocks are not allowed on XML instructions"
              )
            end
          end
    
        end
    
    end
    

    March 17th, 2011 @ 04:22 PM

  26. Valentine Bichkovsky
    Valentine Bichkovsky

    What we did is in my previous message (copied builder 3 files into /lib/builder).

    March 17th, 2011 @ 04:22 PM

  27. johnae
    johnae

    The incompatibility between builder 2.1.2 and amqp has now been resolved and was actually (it seems) a problem with the amqp gem.

    For more info see:
    https://github.com/ruby-amqp/amqp/issues/38#comment_890160

    (fixed in amqp 0.7.1)

    March 18th, 2011 @ 05:45 PM