Ruby’s Singleton and Custom Rails Application Configuration

A relatively simple way to load some configuration once and safely, is through the use of the Singleton module provided with Ruby.

class FooConfig
  include Singleton  
  attr_reader :foo

  def initialize()
    @foo = true
  end
end

Accessing the instance is easy, call FooConfig.instance. This method is also thread-safe so no two threads are going to create/access a different instance. The example is trite, but imagine instead loading data from a remote service. Now combine this with Mike Perham’s Configuration for Rails, the Right Way.

MyApp::Application.config.foo = FooConfig.instance

There is really little reason to access the configuration via Rails.application.config.foo, except that this way you can change it for things like tests more easily.

Speaking of testing, if you find you need to reset a singleton for some reason, the following seems to do the trick, which comes from http://blog.ardes.com/2006/12/11/testing-singletons-with-ruby. Just paste into a file like spec/support/singleton_reset.rb (if using rspec) and require it in spec/spec_helper.rb

require 'singleton'

class <<Singleton
  def included_with_reset(klass)
    included_without_reset(klass)
    class <<klass
      def reset_instance
        Singleton.send :__init__, self
        self
      end
    end
  end
  alias_method :included_without_reset, :included
  alias_method :included, :included_with_reset
end
Advertisements
This entry was posted in rails and tagged , , , . Bookmark the permalink.

One Response to Ruby’s Singleton and Custom Rails Application Configuration

  1. Robert Reiz says:

    Thanks for the article. That helped me a lot.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s