Проблема
Этот вопрос мотивирован попыткой найти решение для этого вопроса.
Предположим, вы хотите построить иерархическую структуру, используя следующий синтаксис:
root {
subA {
subB("b1.1")
subB("b1.2")
}
}
Строительный DSL должен быть типобезопасным, то есть не должно быть возможности вложить subB
непосредственно в root
или вложить subA
в другой subA
. Следовательно, моя идея состоит в том, чтобы иметь метод root
, возвращающий объект, определяющий метод subA
, где последний, в свою очередь, возвращает объект, определяющий subB
.
Теперь я хотел бы, чтобы блок кода передавался root
, то есть
subA {
subB("b1.1")
subB("b1.2")
}
выполняется таким образом, что вызов subB
привязан к объекту, созданному root
. В основном так
root { r: Root =>
r.subA { sa: SubA =>
sa.subB("b1.1")
sa.subB("b1.2")
}
}
но без необходимости явно указывать получателей r
и sa
.
Вопрос. Возможна ли повторная привязка приемников, особенно неявного this
-приемника, внутри блока кода в Scala — возможно, с помощью макросов?
Другие подходы
В этой статье описывается похожее построение DSL для XML-деревьев. Их реализация основана на функции Dynamic
, и результирующий синтаксис DSL выглядит следующим образом:
xml html {
xml head {
xml title "Search Links"
}
}
Однако этот подход требует явных приемников (здесь объект xml
), и, что еще более серьезно, я не думаю, что он безопасен для типов в том смысле, что он статически не позволит вам вложить узел html
в узел title
.