Ruby插件架构

我想要一个非常基本的一个基本程序的例子,读取两个插件注册它们.这两个插件以不冲突的方式以相同的方式挂接到基本程序中.

对于这个问题,我非常喜欢使用任何编程语言进行元编程,我不知道从哪里开始.

解决方法

我一直在处理这个问题一段时间.我已经尝试了许多不同的方法去做,并征求了很多人的意见.我仍然不知道我是否是“正确的方式”,但它的工作很好,很容易做到.

在我的情况下,我特别看配置和引入配置插件,但原理是一样的,即使我的术语是特定于cnfiguration.

在一个非常基本的层面上,我有一个没有配置的配置类 – 它是空的.我还有一个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

有很多选择来实现这个的各个部分,但这应该让你走下去.

相关文章

以下代码导致我的问题: class Foo def initialize(n=0) @n = n end attr_accessor :n d...
这是我的spec文件,当为上下文添加测试“而不是可单独更新用户余额”时,我得到以下错误. require 's...
我有一个拦截器:DevelopmentMailInterceptor和一个启动拦截器的inititializer setup_mail.rb. 但我想将...
例如,如果我有YAML文件 en: questions: new: 'New Question' other: recent: ...
我听说在RSpec中避免它,let,let !,指定,之前和主题是最佳做法. 关于让,让!之前,如果不使用这些,我该如...
我在Rails中使用MongoDB和mongo_mapper gem,项目足够大.有什么办法可以将数据从Mongoid迁移到 Postgres...