根据 Ruby 约定将配置块放在哪里?

Where to put config blocks according to Ruby convention?

哪个更正确? 我知道他们两个 "work" 但是关于放置配置块的约定约定是什么?

这个:

class Something
  Library1.config do |config|
    #call configuration methods
  end

  Library2.config do |config|
    #call configuration methods
  end

  def initialize
    #build the object
  end
end

还是这个?

class Something
  def initialize
    Library1.config do |config|
      #call configuration methods
    end

    Library2.config do |config|
      #call configuration methods
    end

    #build the object
  end
end

没有一个正确答案。你只需要知道在每种情况下你想要什么,因为它们做不同的事情。

  • 前者在 class 首次加载时配置库
  • 后者在每次创建实例时配置库。

两者都是您可能想要的东西,但我可能两者都不

为什么?因为您正在修改许多 class 可能依赖的模块的全局状态,所以您可能只想配置它一次。相反,我会将配置放入一个在初始化时加载的专用配置文件中。这通常在例如rails(参见:rails 项目的 config/ 目录中的所有内容)。

例子

我构建了一个示例来说明不同的行为,以及在更改模块的全局配置时 rouge class (Spoiler) 如何让每个人感到困惑。在此示例中,Spoiler 更改了两次配置,显然影响了 NaiveUser

module Configurable
  def self.configuration
    @configuration ||= { number: 1 }
  end

  def self.config
    yield(configuration)
  end
end

class NaiveUser
  def configurable_number
    Configurable.configuration[:number]
  end
end

puts NaiveUser.new.configurable_number

class Spoiler
  Configurable.config do |c|
    c[:number] = "first spoil"
  end

  def initialize
    Configurable.config do |c|
      c[:number] = "spoiled again"
    end
  end
end

puts NaiveUser.new.configurable_number

Spoiler.new

puts NaiveUser.new.configurable_number

这个程序的输出是

1
first spoil
spoiled again

这个例子可以是扩展到一个示例,其中有状态 NaiveUser 在(错误的)假设配置将保持不变的情况下错误地混合了两种不同配置的结果。