(Отвечая на мой собственный вопрос на тот случай, если решение, которое я использую, будет полезно всем, кто ищет его в будущем)
Не имея чистого способа YAML, я собираюсь реализовать это как «преобразование синтаксиса», которое находится между синтаксическим анализатором YAML и кодом, который фактически использует файл конфигурации. Таким образом, мое основное приложение не должно беспокоиться о каких-либо дружественных для человека мерах по избежанию избыточности и может просто воздействовать непосредственно на полученные структуры.
Структура, которую я собираюсь использовать, выглядит следующим образом:
foo:
MERGE:
- - a
- b
- c
- - 1
- 2
- 3
Что будет преобразовано в эквивалент:
foo:
- a
- b
- c
- 1
- 2
- 3
Или с картами:
foo:
MERGE:
- fork: a
spoon: b
knife: c
- cup: 1
mug: 2
glass: 3
Будет преобразовано в:
foo:
fork: a
spoon: b
knife: c
cup: 1
mug: 2
glass: 3
Более формально, после вызова синтаксического анализатора YAML для получения собственных объектов из файла конфигурации, но перед передачей объектов в остальную часть приложения мое приложение будет обходить граф объектов в поисках сопоставлений, содержащих один ключ MERGE
. Значение, связанное с MERGE
, должно быть либо списком списков, либо списком карт; любая другая подструктура является ошибкой.
В случае списка списков вся карта, содержащая MERGE
, будет заменена дочерними списками, объединенными вместе в порядке их появления.
В случае списка карт вся карта, содержащая MERGE
, будет заменена одной картой, содержащей все пары ключ / значение в дочерних картах. В случаях, когда ключи перекрываются, будет использоваться значение из дочерней карты, которое встречается последним в списке MERGE
.
Приведенные выше примеры не очень полезны, так как вы могли просто написать структуру, которую хотели напрямую. Скорее всего, это будет выглядеть как
foo:
MERGE:
- *salt
- *pepper
Позволяет вам создать список или карту, содержащую все в узлах salt
и pepper
, используемых в других местах.
(я продолжаю давать эту внешнюю карту foo:
, чтобы показать, что MERGE
должен быть ключом only в своем отображении, что означает, что MERGE
не может отображаться в качестве имени верхнего уровня, если нет других имен верхнего уровня нет)