我想要一个基本的小程序示例,它读入两个插件并注册它们.这两个插件以无冲突的方式以相同的方式挂接到基本程序中.
我对任何编程语言的元编程都很陌生,我不知道从哪里开始.
我一直在研究这个问题.我已经尝试了很多不同的方法来做这件事并向很多人寻求建议.我仍然不确定我所拥有的是"正确的方式",但它运作良好而且很容易做到.
在我的情况下,我特别关注配置并引入配置插件,但即使我的术语特定于配置,原理也是一样的.
在一个非常基本的层面上,我有一个没有任何内容的Configuration类 - 它是空的.我还有一个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,你会得到如下所示的输出:
do stuff, here some value is: whatever test that thing
有很多选项来实现这个的各个部分,但这应该让你走上正轨.