Каковы хорошие онлайн-руководства по внедрению DSL в Ruby? Я ищу практические примеры, которые объясняют весь процесс.
Я знаю, что есть этот вопрос о хороших книгах о DSL и Ruby: Хорошие книги по DSL на основе Ruby.
Каковы хорошие онлайн-руководства по внедрению DSL в Ruby? Я ищу практические примеры, которые объясняют весь процесс.
Я знаю, что есть этот вопрос о хороших книгах о DSL и Ruby: Хорошие книги по DSL на основе Ruby.
Я думаю, что это отличная серия статей о создании dsl в ruby:
Вы можете сделать это очень легко с помощью Docile gem, либо используя драгоценный камень, либо прочитав исходный код, чтобы понять, как он работает.
Скажите, что вы хотите сделать Pizza через DSL
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
И вы используете шаблон построителя, чтобы сделать пиццу
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([email protected], [email protected], [email protected], @sauce)
end
end
И вы хотите DSL, скажите что-то вроде
@sauce = :extra
pizza do
bacon
cheese
sauce @sauce
end
# => should return Pizza.new(true, false, true, :extra)
Все, что вам нужно сделать, это определить метод pizza как
require 'docile'
def pizza(&block)
Docile.dsl_eval(PizzaBuilder.new, &block).build
end
И удари, все готово.
Я считаю этот учебник очень хорошим, так как он явно охватывает два очень важных шаблона использования yield
и instance_eval
:
Необходимым условием для написания DSL является понимание некоторых современных методов программирования, таких как уступчивые блоки, процесс поиска метода Ruby и метод_поиск() и т.д. Чтение Метапрограммирование Ruby - лучший способ развить эти продвинутые навыки Ruby (в книге также содержится раздел о написании внутренних DSL).
Я написал сообщение о том, как создать Ruby DSL для генерации HTML-разметки примерно в 20 строках кода. Гораздо лучше начать с некоторых небольших игрушечных примеров, чем перейти прямо к продуктовому классу, например Erector. Изучение исходного кода Docile gem, как было предложено ms-tg, отлично, но это все равно может быть немного подавляющим как ваш первый DSL. Изучите некоторые продвинутые методы программирования Ruby, создайте некоторые примеры игрушек, а затем изучите исходный код Docile.
Здесь, как получить некоторые функции драгоценности Docile, как объяснено @ms-tg с нуля:
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>
Метод dsl()
также может использоваться для более простых примеров, таких как Docile README пример построения массива:
arr = []
dsl(arr) do
push(1)
push(2)
pop
push(3)
end
p arr