Ruby 从要在多个类中使用的配置文件中读取选项的干式方法是什么?

Ruby 从要在多个类中使用的配置文件中读取选项的干式方法是什么?,ruby,configuration-files,Ruby,Configuration Files,对于存储在JSON文件中的程序,我有一些配置选项。我希望能够访问几个不同类中的选项,而不必显式地打开文件并读取每个类中的配置。有没有一个好的,干燥的方法来做到这一点 我试着创建一个模块,将配置读入一个类变量中,并且只在每个类中包含该模块,但是这是一个很好的类变量用法吗?阅读让我对类变量保持警惕 以下是我现在拥有的: 模块配置 @@config=nil def自带(基本) 如果@@config.nil? 打开('config.json','r'){f |@@config=json.load(f)}

对于存储在JSON文件中的程序,我有一些配置选项。我希望能够访问几个不同类中的选项,而不必显式地打开文件并读取每个类中的配置。有没有一个好的,干燥的方法来做到这一点

我试着创建一个模块,将配置读入一个类变量中,并且只在每个类中包含该模块,但是这是一个很好的类变量用法吗?阅读让我对类变量保持警惕

以下是我现在拥有的:

模块配置
@@config=nil
def自带(基本)
如果@@config.nil?
打开('config.json','r'){f |@@config=json.load(f)}
结束
结束
结束
谢谢

更新:

也许将所有需要配置的类放在它自己的名称空间下更好

模块MyFishTank
配置={“位置”=>“我的房间”}
分类鱼
def位置
配置['location']
结束
结束
结束
fish=MyFishTank::fish.new
放置fish.location#=>“我的房间”

为什么不这样做:

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

虽然可能有更简洁的方法来做这件事。

为什么不这样做:

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

虽然可能有更简洁的方法来解决这个问题。

你也可以看看其他人是如何解决这个问题的。例如,检查
RConfig
Configatron

在我的上一个项目中,我使用了Configatron,并且非常喜欢它,但我认为在下一个项目中,我将尝试一下RConfig。Configatron可能内置了太多的魔法,而RConfig看起来更像是一个直截了当的解决方案

你也可以用它们作为基地。我认为您可以很容易地将JSON支持冷添加到RConfig,并为将来的项目提供一个通用的配置解决方案

RConfig:

Configatron:

你可以看看其他人是如何试图解决这个问题的。例如,检查
RConfig
Configatron

在我的上一个项目中,我使用了Configatron,并且非常喜欢它,但我认为在下一个项目中,我将尝试一下RConfig。Configatron可能内置了太多的魔法,而RConfig看起来更像是一个直截了当的解决方案

你也可以用它们作为基地。我认为您可以很容易地将JSON支持冷添加到RConfig,并为将来的项目提供一个通用的配置解决方案

RConfig:

Configatron:

是否有办法避免每次检索配置选项时都键入类名?我可以在每节课上都做
@conf=A.config
,但虽然这是对我以前所做的改进,但我不认为这是完全枯燥的。@cyang:请看编辑后的答案。我不确定省略类方法调用是否会被认为是枯燥的。您提出了一个很好的观点,即配置不仅是实例范围的,而且由于它被应用于不同的类,也许它也不应该被视为类方法?我用另一个选项更新了我的问题,将我的所有类放在具有配置集的命名空间下。这是否违背了任何最佳实践?它应用于不同的类,但通过一个通用的mixin(这正是mixin的用途)。使用名称空间似乎并不合适,因为一个类只能属于一个(直接的)父名称空间,并且您可能有更适合您的类的父名称空间。可配置只是类的另一个特征,甚至不是主要特征。因此,我建议你选择mixins。好的,我明白了。我越看你的解决方案,它就越有意义。非常感谢你的帮助!有没有办法避免每次检索配置选项时都键入类名?我可以在每节课上都做
@conf=A.config
,但虽然这是对我以前所做的改进,但我不认为这是完全枯燥的。@cyang:请看编辑后的答案。我不确定省略类方法调用是否会被认为是枯燥的。您提出了一个很好的观点,即配置不仅是实例范围的,而且由于它被应用于不同的类,也许它也不应该被视为类方法?我用另一个选项更新了我的问题,将我的所有类放在具有配置集的命名空间下。这是否违背了任何最佳实践?它应用于不同的类,但通过一个通用的mixin(这正是mixin的用途)。使用名称空间似乎并不合适,因为一个类只能属于一个(直接的)父名称空间,并且您可能有更适合您的类的父名称空间。可配置只是类的另一个特征,甚至不是主要特征。因此,我建议你选择mixins。好的,我明白了。我越看你的解决方案,它就越有意义。非常感谢你的帮助!