«زبان دامنهاختصاصی» (DSL) زبانی کوچک است که برای یک دامنهی مشخص بهینه شده است. از آنجا که DSL هدفمند است، با این امکان را به نویسنده میدهد که بهجای چگونه، بگوید چه میخواهد؛ همین میتواند بهرهوری و درک را بهشدت افزایش دهد.
یکی از حوزههایی که این زبانها در آن به کار میروند، سفارشیسازیها و پیکربندیهای پیچیده است.
برای مثال، زبان DOT به شما اجازه میدهد توصیف متنی یک گراف را بنویسید که سپس یکی از ابزارهای Graphviz (مانند dot) آن را به تصویر تبدیل میکند.
یک گراف ساده اینگونه است:
graph {
graph [bgcolor="yellow"]
a [color="red"]
b [color="blue"]
a -- b [color="green"]
}
اگر این را در فایلی به اسم example.dot قرار دهید و dot example.dot -T png -o example.png را اجرا کنید، تصویری به اسم example.png ساخته میشود که در آن دایرهای قرمز و دایرهای آبی روی پسزمینهای زرد با خطی سبز به هم وصل شدهاند.
یک زبان دامنهاختصاصی مشابه زبان dot در Graphviz بنویسید.
DSL ما از این نظر مشابه زبان dot در Graphviz است که برای ساختن ساختارهای دادهی گراف به کار میرود. اما برخلاف زبان DOT، DSL ما یک DSL درونی است که فقط در زبان خودمان به کار میرود.
دربارهی تفاوت DSLهای درونی و بیرونی بیشتر بدانید.
در این تمرین، کاملاً آزاد هستید که DSL گرافِ دلخواه خودتان را طراحی کنید.
شاید بخواهید DSLای بر پایهی فهرستهایی از برچسبها و رکوردها بسازید، مثل این:
my_graph =
Graph.create([
Title("My Graph"),
Node("a", { color: Green }),
Node("b", { color: Blue }),
Edge("a", "b", { style: Dotted }),
])
یا شاید DSLای را ترجیح میدهید که بر پایهی زنجیرهای از فراخوانی توابع بنا شده باشد، مثل این:
my_graph =
Graph.create()
.with_title("My Graph")
.add_node("a", Attr.create().with_color(Green))
...
یا شاید برنامهی کاملاً متفاوتی دارید؟ بفرمایید! Testها فقط میخواهند چند گراف مشخص بسازید؛ اینکه چطور آنها را بسازید کاملاً به خودتان بستگی دارد.
با این حال، یک DSL معمولاً وقتی بهتر است که روشن، مختصر و چندان غافلگیرکننده نباشد (مثلاً تابع minus برای تفریق در نظر گرفته شده، نه برای ساختن یالی بین دو گره، مثل node("a") - node("b")).
برای اینکه سرگرمی دو برابر شود، میتوانید بهصورت اختیاری تابع to_dot را پیادهسازی کنید که گراف شما را به قالب DOT تبدیل میکند!