Last Updated: February 25, 2016
·
1.95K
· pyromaniac

Robust gem configuration

Assume, you have a ruby gem named YACG (Yet Another Coolest Gem). And you need base parameters configured by user. The traditional way is:

module YACG
  mattr_accessor :do_cool_things
  @do_cool_things = true

  mattr_accessor :cool_handlers
  @@cool_handlers = {}

  def register_handler name, handler
    @@cool_handlers[name] = handler
  end
end

or something similar.

But there is another way with huge amount of benefits. You can move your config to singleton class like this:

module YACG
  class Config
    include Singleton

    attr_accessor :do_cool_things, :cool_handlers

    def initialize
      @do_cool_things = true
      @cool_handlers = {}
    end

    def register_handler name, handler
      @cool_handlers[name] = handler
    end
  end
end

In this case you have a class, which might be tested really easy:

describe YACG::Config do
  subject { described_class.send(:new) }

  describe '#register_handler' do
    before { subject.register_handler :cool, -> {} }
    specify { subject.handlers.should have_key(:cool) }
  end
end

After you just delegate your main module's class methods to the config instance:

module YACG
  def self.config
    Config.instance
  end

  singleton_class.delegate :do_cool_things, :cool_handlers, to: :config
end

That's all. Now you have well-tested, isolated and handy gem configuration. You can look for example at the hotcell gem.