blog.absurd:li - press play on tape
September 16th 2009
Tagged rails, ruby, gotcha, class reloading

How to prevent class unloading in Ruby on Rails

Let’s assume you have a class that holds a connection to an external system, and you don’t want Rails auto(un)loading to mess with that. The advice the rails documentation gives you in this case is simple and correct: Just don’t let rails autoload your class, instead, require it yourself.

  require 'my_persistent_class'

There is one gotcha to this, and a gotcha that conflicts with the natural ordering tendency that every programmer should have. Let’s say you’re extending a rails model with FeatureX. It will come natural to you to name that module RailsModel::FeatureX. This has consequences.

There is no real way to ‘load’ that RailsModel by using a require – when would you do it? During initialization process, this fails because rails obviously isn’t in place yet. And later on – rails will be in place and the RailsModel class will already be in the fangs of autoloading.

And the next time rails autounloads/ autoloads classes, RailsModel – and with it FeatureX – will be reloaded as well. Darn. The solution to this is really simple, but it took me a while to figure this out: Just don’t include the FeatureX class in the namespace of RailsModel. Then doing this in your environment.rb will ensure that your FeatureX isn’t unloaded:

  config.after_initialize do
    require 'feature_x'
    FeatureX.set_some_persistent_attribute :foo => :bar

Btw: Global variables are really evil.