Подтвердить что ты не робот

Учебники для написания DSL в Ruby

Каковы хорошие онлайн-руководства по внедрению DSL в Ruby? Я ищу практические примеры, которые объясняют весь процесс.

Я знаю, что есть этот вопрос о хороших книгах о DSL и Ruby: Хорошие книги по DSL на основе Ruby.

4b9b3361

Ответ 2

Вы можете сделать это очень легко с помощью 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

И удари, все готово.

Ответ 4

Необходимым условием для написания 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