Я уже давно работаю над этой самой проблемой. Я попробовал несколько разных способов сделать это и обратился за советом ко многим людям. Я до сих пор не уверен, что то, что у меня есть, - «правильный путь», но это хорошо работает и легко сделать.
В моем случае я специально смотрю на конфигурацию и добавляю конфигурационные плагины, но принцип тот же, даже если моя терминология специфична для конфигурации.
на самом базовом уровне, у меня есть класс конфигурации, в котором ничего нет - он пустой. У меня также есть метод 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
Есть много вариантов реализации различных частей этого, но это должно увести вас с пути.