Ruby Plugin Architecture - PullRequest
       8

Ruby Plugin Architecture

11 голосов
/ 24 июня 2010

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

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

Ответы [ 2 ]

9 голосов
/ 24 июня 2010

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

В моем случае я специально смотрю на конфигурацию и добавляю конфигурационные плагины, но принцип тот же, даже если моя терминология специфична для конфигурации.

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

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

2 голосов
/ 26 января 2011

Похоже, этот проект может помочь: https://github.com/eadz/plugman

Однако я не нашел ничего, что могло бы обрабатывать встроенные (gem) зависимости.Включать файлы Ruby просто, но как только ваши плагины начинают нуждаться в других библиотеках, эта простая модель разваливается (либо все deps должны быть установлены вместе с вашим приложением, либо вам нужен какой-то другой механизм для добавления гемов зависимости плагина в процесс).1004 *

...