views:

43

answers:

1

I've just recently started writing my own gems. One of them requires the gnuplot gem, like so:

module Rocker
  require "gnuplot"
  # ... module code here ...
end

It works great, right up until I add my gem to config/environment.rb on one of my Rails projects. Then, not a single page will load. I get errors like this:

TypeError in Matrices#show

Showing app/views/matrices/_detail.html.erb where line #13 raised:

can't dup NilClass

The trace goes on, but it's pretty useless. It's clear to me that gnuplot is creating some kind of conflict.

Is there an equivalent of config/environment.rb for gems? I understand you're not supposed to require "rubygems" anymore within a gem. What's the correct way of making gems available to my custom gems?

(And yes, I suspect I could just add gnuplot as a dependency in my Rails application, but then my gem won't pass its unit tests.)


The full trace was requested. First of all, I'm using the acts_as_commentable plugin, and when gnuplot is required, that gives an error:

$ script/server
=> Booting WEBrick
=> Rails 2.3.5 application starting on http://0.0.0.0:3002
/home/jwoods/NetBeansProjects/crossval/vendor/rails/activerecord/lib/active_record/base.rb:1959:in `method_missing': undefined local variable or method `acts_as_commentable' for #<Class:0xb6889710> (NameError)
    from /home/jwoods/NetBeansProjects/crossval/app/models/matrix.rb:98
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:521:in `new_constants_in'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
    from /usr/lib/ruby/1.8/gnuplot.rb:6
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:521:in `new_constants_in'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
    from /var/lib/gems/1.8/gems/rocker-0.1.2/lib/rocker.rb:10
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:521:in `new_constants_in'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
    from /home/jwoods/NetBeansProjects/crossval/config/../vendor/rails/railties/lib/rails/gem_dependency.rb:208:in `load'
    from /home/jwoods/NetBeansProjects/crossval/config/../vendor/rails/railties/lib/initializer.rb:307:in `load_gems'
    from /home/jwoods/NetBeansProjects/crossval/config/../vendor/rails/railties/lib/initializer.rb:307:in `each'
    from /home/jwoods/NetBeansProjects/crossval/config/../vendor/rails/railties/lib/initializer.rb:307:in `load_gems'
    from /home/jwoods/NetBeansProjects/crossval/config/../vendor/rails/railties/lib/initializer.rb:164:in `process'
    from /home/jwoods/NetBeansProjects/crossval/config/../vendor/rails/railties/lib/initializer.rb:113:in `send'
    from /home/jwoods/NetBeansProjects/crossval/config/../vendor/rails/railties/lib/initializer.rb:113:in `run'
    from /home/jwoods/NetBeansProjects/crossval/config/environment.rb:9
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:521:in `new_constants_in'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
    from /home/jwoods/NetBeansProjects/crossval/vendor/rails/railties/lib/commands/server.rb:84
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
    from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
    from script/server:11

If I comment out the acts_as_commentable line from class Matrix, the server starts. But when I try to load one of the Matrix views, I get two other traces:

ActionView::TemplateError (A copy of Experiment has been removed from the module tree but is still active!) on line #19 of app/views/matrices/index.html.erb:
16:             <li>cells: <%= predict_matrix.cells.count %></li>
17:             <li>density: <%= fractional_density(predict_matrix) %></li>
18:             <li>folds: <%= predict_matrix.children.count %> / <%= predict_matrix.has_grandchildren? ? 2 : 1 %></li>
19:             <li><%= experiments_progress_bar(predict_matrix) %></li>
20:           </ul>
21: 
22:           <%= link_to 'New experiment', new_matrix_experiment_path(predict_matrix) %>

    app/helpers/matrices_helper.rb:104:in `experiments_progress_bar'
    app/views/matrices/index.html.erb:19
    app/views/matrices/index.html.erb:9:in `each'
    app/views/matrices/index.html.erb:9
    app/views/matrices/index.html.erb:4:in `each_pair'
    app/views/matrices/index.html.erb:4
    app/controllers/matrices_controller.rb:83:in `index'
    /usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
    /usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
    /usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
    /usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
    /usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
    /usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
    /usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
    /usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
    /usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
    /usr/lib/ruby/1.8/webrick/server.rb:82:in `start'

Rendered rescues/_trace (36.1ms)
Rendered rescues/_request_and_response (0.2ms)
Rendering rescues/layout (internal_server_error)

and this one:

ActionView::TemplateError (can't dup NilClass) on line #13 of app/views/matrices/_detail.html.erb:
10:     <li class="submatrix_info">Submatrices
11:       <ul>
12:         <% matrix.children.each do |child| %>
13:         <li><%= link_to child.id, matrix_path(child), :class => "submatrix_link" %><%= experiments_progress_bar(child) %></li>
14:         <% end %>
15:       </ul>
16:     </li>

    app/helpers/matrices_helper.rb:104:in `experiments_progress_bar'
    app/views/matrices/_detail.html.erb:13
    app/views/matrices/_detail.html.erb:12
    app/views/matrices/show.html.erb:12
    app/controllers/matrices_controller.rb:28:in `show'
    /usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
    /usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
    /usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
    /usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
    /usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
    /usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
    /usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
    /usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
    /usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
    /usr/lib/ruby/1.8/webrick/server.rb:82:in `start'

Rendered rescues/_trace (74.6ms)
Rendered rescues/_request_and_response (0.2ms)
Rendering rescues/layout (internal_server_error)
A: 

This article explains everything quite clearly...

http://tomayko.com/writings/require-rubygems-antipattern

Chris Amini
This only explains why not to include rubygems. It does not help with the gnuplot problem at all.
mohawkjohn