Архитектура плагина Ruby

Я хотел бы очень простой пример крошечной основной программы, которая читает в двух плагинах и регистрирует их. Эти два плагина сцепляются в основную программу таким же образом в неконфликтующем способе.

Я очень плохо знаком с метапрограммированием на любом языке программирования в этом отношении, я не уверен, где запустить.

11
задан 24 June 2010 в 18:07
поделиться

1 ответ

Я уже давно работаю над этой самой проблемой. Я пробовал несколько разных способов сделать это и советовался по этому поводу со многими людьми. Я все еще не уверен, что то, что у меня есть, является «правильным», но он работает хорошо и его легко сделать.

В моем случае я специально смотрю на конфигурацию и добавляю подключаемые модули конфигурации, но принцип тот же, даже если моя терминология специфична для 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

есть много вариантов реализации различных частей этого, но это должно помочь вам.

9
ответ дан 3 December 2019 в 09:40
поделиться