ruby - arbre - active admin panel
Tutoriales para escribir DSL en Ruby (4)
¿Cuáles son los buenos tutoriales en línea sobre cómo implementar DSL en Ruby? Estoy buscando ejemplos prácticos que expliquen todo el proceso.
Soy consciente de que existe esta pregunta sobre buenos libros sobre DSL y Ruby: buenos libros sobre DSL basada en Ruby .
Creo que esta es una gran serie de artículos sobre la construcción de una DSL en rubí:
Encuentro este tutorial muy bueno, ya que cubre explícitamente los dos patrones muy importantes de usar yield
y instance_eval
:
Puedes hacer esto muy fácil con la gem Docile , ya sea usando la gema o leyendo el código fuente para entender cómo funciona.
Digamos que quieres hacer una pizza a través de una DSL
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
Y usas un patrón de construcción para hacer la pizza
class PizzaBuilder
def cheese(v=true); @cheese = v; end
def pepperoni(v=true); @pepperoni = v; end
def bacon(v=true); @bacon = v; end
def sauce(v=nil); @sauce = v; end
def build
Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce)
end
end
Y quieres un DSL , di algo como
@sauce = :extra
pizza do
bacon
cheese
sauce @sauce
end
# => should return Pizza.new(true, false, true, :extra)
Todo lo que tienes que hacer es definir el método de pizza como
require ''docile''
def pizza(&block)
Docile.dsl_eval(PizzaBuilder.new, &block).build
end
Y bang, ya terminaste.
Un requisito previo para escribir un DSL es entender algunas técnicas avanzadas de programación como bloques de rendimiento, el método de búsqueda de método de Ruby y method_missing (), etc. Leer Metaprogramación Ruby es la mejor manera de desarrollar estas habilidades avanzadas de Ruby (el libro también contiene una sección sobre escritura interna DSL).
Escribí una publicación de blog sobre cómo crear una DSL de Ruby para generar etiquetas HTML en aproximadamente 20 líneas de código. Es mucho mejor comenzar con algunos ejemplos de juguetes pequeños, que ir directamente a una aplicación de nivel de producción como Erector . Estudiar el código fuente de la gema Docile como lo sugiere ms-tg es excelente, pero aún así puede ser un poco abrumador como tu primer DSL. Aprende algunas técnicas avanzadas de programación de Ruby, construye algunos ejemplos de juguetes y luego estudia el código fuente de Docile.
A continuación se detalla cómo obtener parte de la funcionalidad de la gema Docile, tal como lo explica @ ms-tg desde cero:
def dsl(obj, &block)
obj.instance_eval(&block)
end
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
obj = Pizza.new
dsl(obj) do |pizza|
pizza.cheese = true
pizza.pepperoni = true
pizza.sauce = :extra
end
p obj
# => #<struct Pizza cheese=true, pepperoni=true, bacon=nil, sauce=:extra>
El método dsl()
también se puede utilizar para ejemplos más triviales, como el ejemplo de README de Docile de construir una matriz:
arr = []
dsl(arr) do
push(1)
push(2)
pop
push(3)
end
p arr