Что такое СУХОЙ способ чтения параметров из файла конфигурации, который будет использоваться в нескольких классах? - PullRequest
0 голосов
/ 08 июля 2011

У меня есть несколько параметров конфигурации для программы, хранящейся в файле JSON.Я хочу иметь возможность доступа к опциям в нескольких разных классах без явного открытия файла и чтения конфигурации в каждом классе.Есть ли хороший, СУХОЙ способ сделать это?

Я попытался создать модуль, который считывает конфигурацию в переменную класса и просто включает модуль в каждый класс, но хорошо ли это использовать переменные класса?Чтение этого заставляет меня настороженно относиться к переменным класса.

Вот что я имею сейчас:

module Config
  @@config = nil

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

Спасибо!

Обновление:

Может быть, лучше просто поместить все классы, для которых требуется конфигурация, в собственное пространство имен?

module MyFishTank
  Config = { "location" => "My room" }

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

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

Ответы [ 2 ]

2 голосов
/ 08 июля 2011

Вы можете посмотреть, как другие пытались решить эту проблему. Например, проверьте RConfig или Configatron.

В моем последнем проекте я использовал Configatron, и он мне очень понравился, но я думаю, что для следующего проекта я собираюсь дать RConfig шанс. В Configatron может быть слишком много волшебства, и RConfig выглядит как более прямолинейное решение.

Вы также можете использовать их в качестве базы. Я думаю, что вы довольно легко добавили поддержку JSON в RConfig, и у вас есть обобщенное конфигурационное решение для будущих проектов ...

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

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

1 голос
/ 08 июля 2011

Почему бы не что-то вроде этого:

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

Редактировать: если вы хотите избежать вызова метода класса (что мне кажется неправильным, поскольку конфигурация действительно для всего класса, а не для экземпляра), вы можете сделать что-то вроде:

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

Хотя, возможно, есть более лаконичный способ сделать это.

...