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 .
4 answers
Myślę, że jest to świetna seria artykułów na temat budowania dsl w ruby:
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.
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
:
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
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