Tutoriale do pisania DSL w Ruby

Jakie są dobre samouczki online jak zaimplementować DSLs w Ruby? Szukam praktycznych przykładów, które wyjaśnią cały proces.

Zdaję sobie sprawę, że jest takie pytanie na temat dobrych książek o DSLs i Ruby: dobre książki na bazie Ruby DSL .

 31
Author: Community, 2011-02-08

4 answers

Myślę, że jest to świetna seria artykułów na temat budowania dsl w ruby:

Http://jroller.com/rolsen/entry/building_a_dsl_in_ruby

 34
Author: Upgradingdave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-08 17:45:45

Możesz zrobić to bardzo łatwo z potulny gem, albo używając gem, albo czytając kod źródłowy, aby zrozumieć, jak to działa.

Powiedz, że chcesz zrobić pizzę przez DSL

Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)

I używaszbuilder pattern do zrobienia pizzy

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

I chcesz DSL, powiedz coś w stylu

@sauce = :extra
pizza do
  bacon
  cheese
  sauce @sauce
end
# => should return Pizza.new(true, false, true, :extra)

Wystarczy zdefiniować metodę pizza jako

require 'docile'

def pizza(&block)
  Docile.dsl_eval(PizzaBuilder.new, &block).build
end

I bang, jesteś skończony.

 34
Author: ms-tg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-26 15:04:10

Uważam ten samouczek za bardzo dobry, ponieważ wyraźnie obejmuje dwa bardzo ważne wzorce używania yield i instance_eval:

Jak zbudować DSL z yield I instance_eval?

 4
Author: Alex Popov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-17 00:52:17

Warunkiem pisania DSL jest zrozumienie niektórych zaawansowanych technik programowania, takich jak yielding blocks, metoda Ruby lookup process I method_missing(), itp. Czytanie Metaprogramowanie Rubiego jest najlepszym sposobem na rozwinięcie tych zaawansowanych umiejętności Rubiego(książka zawiera również sekcję dotyczącą pisania wewnętrznych DSL).

Napisałem post na blogu o tym, jak utworzyć Ruby DSL, aby wygenerować znaczniki HTML w około 20 linijkach kodu. Dużo lepiej zacząć od małej zabawki przykłady, niż wskoczyć do aplikacji klasy produkcyjnej, takiej jak Erector . Badanie kodu źródłowego potulnego klejnotu zgodnie z sugestią ms-tg jest doskonałe, ale nadal może być nieco przytłaczające jako twój pierwszy DSL. Naucz się zaawansowanych technik programowania w języku Ruby, zbuduj kilka zabawkowych przykładów, a następnie przestudiuj posłuszny kod źródłowy.

Oto jak uzyskać część funkcjonalności potulnego klejnotu, jak wyjaśnia to @ms-TG od podstaw:

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>

The dsl() metoda może być również używana do bardziej trywialnych przykładów, jak przykład Potile README konstruowania tablicy:

arr = []

dsl(arr) do
  push(1)
  push(2)
  pop
  push(3)
end

p arr
 1
Author: Powers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-13 04:51:58