so Rails 1.2 might be nice, but I got some HUGE headaches when migrating to Rails 1.2. This time, all my ActiveRecord objects were raising a "private method `equal?' called for #
With Rails 1.1.6 everything was OK, but with Rails 1.2, I started to get errors like:
private method `equal?' called for #
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/active_support/core_ext/class/inheritable_attributes.rb:127:in `inherited_without_layout'
/usr/lib/ruby/gems/1.8/gems/actionpack- 1.13.2/lib/action_controller/layout.rb:185:in `inherited_without_helper'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_controller/helpers.rb:120:in `inherited_without_api'
/usr/lib/ruby/gems/1.8/gems/actionwebservice- 1.2.2/lib/action_web_service/container/action_controller_container.rb:84:in `inherited_without_action_controller'
/usr/lib/ruby/gems/1.8/gems/actionwebservice-1.2.2/lib/action_web_service/dispatcher/action_controller_dispatcher.rb:32:in `inherited'
./script/../config/../app/controllers/application.rb:6
The problem with ruby is that each framework attempts discretely to do its own magic by redefining existing methods. But frameworks end up crunching themselves this way. That's pretty much the same knd of trouble I had with gettext (see previous post)
After looking quite a while at the code, I had no idea what object was this Hash:0xb74e20fc object neither why ActiveSupport would care about it. Adding some debug logs into ActiveSupport, I saw that all GSL objects are being handled by ActiveSupport but again, I found no way to prevent such a nasty exception to occur.
At the end, I found a dirty compromise to continue using rb-gsl in my Rails app:
First it implies you patch ActiveSupport (1.4.1 in my case) to look if the method 'equal?' isn't private as it would just occur with rb-gsl:
add this method visibility check line 127 of
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/active_support/core_ext/class/inheritable_attributes.rb
if (!inheritable_attributes.private_methods.index('equal?')) && inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
(hint: you can use that check to log the problematic 'child' object if you want to debug Rails or rb-gsl)
Second, we can't require 'rb-gsl' inside an ActiveRecord object (neither a module included in an ActiveRecord object) anymore because even if we avoid the first illegal access to the private method, a there is a second catch that would break out later: 'can't change a frozen Hash', go understand...
So you'll have to encapsulate your rb-gsl lib inside some wrapping ruby object that will contains require 'gsl' and provide ruby methods to the gsl methods you are interrested in. And eventually your controllers or ActiveRecord object will play with that wrapper to call the gsl math functions.
Yes, overall, doing that really sucks, does anyone have a better idea? Who is the culprit? Rails or rb-gsl? If rb-gsl, how modify it to make it Rails compliant again?
NB: Paul King also noticed this bug with rb-gsl:
http://rubyforge.org/pipermail/mongrel-users/2007-January/002659.html
but he could eventually add a stub empty equal? method to its problematic object. This didn't work at all in my case though.