2010-06-24 19 views
10

Me gustaría un ejemplo muy básico de un pequeño programa base, que se lea en dos complementos y los registre. Estos dos complementos se enganchan en el programa base de la misma manera de manera no conflictiva.Ruby Plugin Architecture

Soy muy nuevo en la metaprogramación en cualquier lenguaje de programación para el caso, no estoy seguro de por dónde empezar.

+1

Perdón por ser pedante, pero no son complementos asociados con el framework de Rails, ¿no con Ruby? –

+0

El framework Rails tiene complementos, pero estoy hablando de crear un sistema de complementos en el contexto de una aplicación de ruby. Entonces di que tienes una clase que lee un archivo de texto. Me gustaría crear un sistema de complemento que te permita escribir una clase de complemento que se enganche en la clase de lector para que puedas decir, un complemento de UpCase o un complemento 1337 que modifique la salida. Es un ejemplo básico, pero eso debería darte una idea. –

+5

ruby ​​es mucho más que rieles, incluso si los rieles son el marco más conocido que existe. decir que los complementos están asociados con los rieles es como decir que la gasolina está asociada con los autos deportivos. hay un mundo de otras cosas que usan gasolina, incluso cosas que no son vehículos de motor. –

Respuesta

8

He estado trabajando en este mismo problema desde hace un tiempo. He intentado varias formas diferentes de hacerlo y busqué el consejo de mucha gente sobre él. Todavía no estoy seguro de si lo que tengo es "el camino correcto", pero funciona bien y es fácil de hacer.

en mi caso, estoy buscando específicamente en la configuración y traer complementos de configuración, pero el principio es el mismo, incluso si la terminología para el mío es específica de la configuración.

en un nivel muy básico, tengo una clase de configuración sin nada, está vacía. También tengo un método Configurar que devuelve la clase de configuración y le permite llamar a métodos en él:

# 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}" 

para obtener el some_method y some_value en la clase de configuración, tengo los plugins amplían el objeto de configuración a través de módulos:

# plugins/myconfig.rb 
module MyConfiguration 
    attr_accessor :some_value 

    def some_method 
    puts "do stuff, here" 
    end 
end 

class Configuration 
    include MyConfiguration 
end 

y

# plugins/another.rb 
module AnotherConfiguration 
    attr_accessor :test 
end 

class Configuration 
    include AnotherConfiguration 
end 

para cargar los plugins, que sólo necesita un código de buscar los archivos .RB en una carpeta específica y 'necesita' ellos . este código puede vivir en cualquier lugar siempre que se ejecute de inmediato cuando se cargue el archivo que lo contiene ... probablemente lo pondría en la definición de clase de MySystem o algo así para empezar. tal vez moverlo a otro lugar cuando tenga sentido.

Dir.glob("plugins/**/*.rb").each{|f| require f}

plazo config.rb y obtendrá salida que se parece a esto:

do stuff, here 
some value is: whatever 
test that thing 

hay una gran cantidad de opciones para la implementación de las diversas partes de este, pero esto debe conseguirle abajo de la camino.

2

Parece que este proyecto puede ayudar a: https://github.com/eadz/plugman

que sin embargo no han encontrado nada que manejará incorporado (GEM) Dependencias sin embargo. Incluir archivos Ruby es sencillo, pero una vez que sus complementos comiencen a necesitar otras bibliotecas, este simple modelo se desmorona (o bien todos los productos deben instalarse con su aplicación, o necesita algún otro mecanismo para incorporar las gemas de dependencia del complemento en el proceso).