开发者

What is a DRY way to read options from a configuration file to be used in multiple classes?

I have some configuration options for a program stored in a JSON file. I want to be able to access the options in several different classes without explicitly having to open the file and read the configuration in each class. Is there a good, DRY way to do this?

I tried creating a module which reads the configuration into a class variable, and just include the module in every class, but is this a good use of class variables? Reading this makes me wary of class variables.

Here is what I have right now:

module Config
  @@config = nil

  def self.included(base)
    if @@config.nil?
      open('config.json', 'r') { |f| @@config = JSON.load(f) }
    end
  end
end

Thanks!

Update:

Maybe it's better just to place all the classes that require the configuration under it's own namespace?

module MyFishTank
  Config = { "lo开发者_开发知识库cation" => "My room" }

  Class Fish
    def location
      Config['location']
    end
  end
end

fish = MyFishTank::Fish.new
puts fish.location #=> "My room"


You could look at how others have tried to solve this problem also. For example check out RConfig or Configatron.

In my last project I used Configatron, and quite liked it, but I think for the next project I'm going to give RConfig a shot. Configatron may have a bit too much magic built into it, and RConfig looks like a more straight forward solution.

You could also use them as a base. I think you cold add JSON support to RConfig quite easily, and have a generalized config solution from there for future projects too...

RConfig:
https://github.com/rahmal/rconfig

Configatron:
https://github.com/markbates/configatron


Why not something like this:

module Configured
  def config
    # memoize config upon load
    @config ||= 'foo'
  end
end

class A
  extend Configured

  def initialize
    puts A.config # or
    puts self.class.config
  end
end

A.new
#=> foo

Edit: if you want to avoid class method invocation (which seems wrong to me, as the configuration is indeed class-wide, not instance-wide), you can do something like:

module Configured
  def self.included(base)
    base.define_singleton_method :config do
      @config ||= 'foo'
    end
  end

  def config
    self.class.config
  end
end

class A
  include Configured

  def initialize
    puts config
  end
end

A.new

Though there probably is more succinct way of doing it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜