«زبان دامنهاختصاصی» (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، شیئی از نوع Graph است. این یک list از یک یا چند تاپل میگیرد که موارد زیر را توصیف میکنند:
NodesEdgesپیادهسازیهای Node و Edge در dot_dsl.py ارائه شدهاند.
برای جزئیات بیشتر دربارهی طراحی مورد انتظار DSL و انواع و پیامهای خطای مورد انتظار، نگاهی به موارد تست در dot_dsl_test.py بیندازید
گاهی لازم است یک استثنا ایجاد کنید. وقتی این کار را میکنید، باید همیشه یک پیام خطای گویا بگنجانید که نشان دهد منبع خطا چیست. این کار کد شما را خواناتر میکند و به شکل چشمگیری به اشکالزدایی کمک میکند. در موقعیتهایی که میدانید منبع خطا از یک نوع مشخص خواهد بود، میتوانید یکی از انواع خطای توکار را ایجاد کنید، اما همچنان باید پیامی گویا بگنجانید.
این تمرین بهطور خاص میخواهد که از دستور raise استفاده کنید تا وقتی Graph بدشکل است، یک TypeError «پرتاب» کنید و وقتی Edge، Node یا attribute بدشکل است، یک ValueError پرتاب کنید. تستها تنها در صورتی قبول میشوند که هم exception را raise کنید و هم پیامی همراه آن بگنجانید.
برای اینکه خطایی همراه با پیام ایجاد کنید، پیام را بهعنوان آرگومان به نوع exception بدهید:
# Graph is malformed
raise TypeError("Graph data malformed")
# Edge has incorrect values
raise ValueError("EDGE malformed")