我已经研究这个问题一段时间了。我尝试了许多不同的方法来做这件事,并征求了很多人的建议。我仍然不确定我所拥有的是否是“正确的方法”,但它运作良好并且很容易做到。
就我而言,我专门研究配置并引入配置插件,但即使我的术语是特定于配置的,原理也是一样的。
在一个非常基本的级别上,我有一个配置类,其中没有任何内容 - 它是空的。我还有一个 Configure 方法,它返回配置类并让您在其上调用方法:
# config.rb
class Configuration
end
class MySystem
def self.configure
@config ||= Configuration.new
yield(@config) if block_given?
@config
end
Dir.glob("plugins/**/*.rb").each{|f| require f}
end
MySystem.configure do |config|
config.some_method
config.some_value = "whatever"
config.test = "that thing"
end
puts "some value is: #{MySystem.configure.some_value}"
puts "test #{MySystem.configure.test}"
为了获得配置类的 some_method 和 some_value,我让插件通过模块扩展配置对象:
# plugins/myconfig.rb
module MyConfiguration
attr_accessor :some_value
def some_method
puts "do stuff, here"
end
end
class Configuration
include MyConfiguration
end
和
# plugins/another.rb
module AnotherConfiguration
attr_accessor :test
end
class Configuration
include AnotherConfiguration
end
要加载插件,您只需要一个代码来查找特定文件夹中的 .rb 文件并“要求”它们。只要在加载包含它的文件时立即运行,此代码就可以存在于任何地方......我可能会将它放在 MySystem 的类定义中或类似的东西开始。可能会在有意义的情况下将其移至其他地方。
Dir.glob("plugins/**/*.rb").each{|f| require f}
运行 config.rb,你会得到如下所示的输出:
做事,在这里
一些价值是:不管
测试那个东西
有很多选项可以实现它的各个部分,但这应该会让你走上正轨。