YAML — недооцененный язык разметки. JSON гораздо более распространен в наши дни для управления конфигурацией. Вероятно, это связано с тем, что это стандарт де-факто для JavaScript… Однако это не объясняет, почему все другие языки также выбирают его, когда YAML просто лучше.

Цель этой статьи — выделить и продемонстрировать некоторые функции, о которых вы, возможно, не знали, кроме базового синтаксиса. Если вы никогда раньше не видели YAML, есть образец документа в Википедии.

1. YAML — это надмножество JSON.

Да это правильно. Вы можете вставить свой JSON непосредственно в файл YAML, и он будет точно таким же образом разрешен с помощью парсеров YAML. JSON можно встроить в любое место внутри YAML. Например:

foo:
  bar: {"baz": [123, 456]}

Все равно что написать:

foo:
  bar:
    baz:
      - 123
      - 456

Использование JSON на месте часто полезно по нескольким причинам:

  1. Вы создаете файл конфигурации из предоставленного извне JSON. Таким образом, нет необходимости конвертировать полученный JSON.
  2. Объект JSON может представлять сложный тип, который следует сократить до одной строки; как позиция: {"x": 10, "y": 20, "z": 15}.
  3. Вы ленивы и предпочитаете набирать JSON.

2. Мультидокументы

YAML поддерживает несколько документов в одном файле. Они разделены --:

---
time: 20:03:20
player: Sammy Sosa
action: strike (miss)
---
time: 20:03:47
player: Sammy Sosa
action: grand slam

3. Комментарии

Некоторые синтаксические анализаторы JSON поддерживают встроенные комментарии с помощью комментариев JavaScript. Однако подавляющее большинство из них этого не делает, поскольку это не часть стандарта JSON.

Все парсеры YAML поддерживают комментарии с #, что бесценно, когда вам нужно объяснить в самой конфигурации (наиболее подходящее место для размещения этой документации):

dev:
    # We have to use 1234 on development because...
    redis_options: {"port": 1234}

Комментарии не обязательно размещать на отдельной строке:

message:
  subject: Hi # The message title

4. Сложные ключи

Традиционно ваши ключи ограничены всем, что может быть представлено в виде строки. YAML позволяет создавать сложные ключи, используя любой тип данных в качестве самого ключа:

? - Detroit Tigers
  - Chicago cubs
:
  - 2001-07-23

Это не сокращение для записи нескольких ключей с одинаковым значением. Сам ключ представляет собой массив. Другой пример с другим синтаксисом:

? [ New York Yankees,
    Atlanta Braves ]
: [ 2001-07-02, 2001-08-12,
    2001-08-14 ]

5. Многострочный текст

Многострочный текст, особенно когда необходимо сохранить пробелы, может быть особенно сложным в обслуживании. YAML предоставляет несколько различных синтаксисов для многострочного текста.

name: Mark McGwire
accomplishment: >
  Mark set a major league
  home run record in 1998.
stats: |
  65 Home Runs
  0.278 Batting Average
  • > преобразует новые строки в пробелы и игнорирует отступы, так что значение accomplishment равно Mark set a major league home run record in 1998.
  • | поддерживает новые строки, но по-прежнему удаляет отступы из блока, поэтому значение stats равно 5 Home Runs\n0.278 Batting Average
  • |- работает как |, но не добавляет последнюю новую строку.

6. Дополнительные типы данных

null числа, строки, массивы и карты поддерживаются так же, как JSON, но YAML также может распознавать другие типы, специфичные для языка, такие как даты и временные метки:

canonical: 2001-12-15T02:59:43.1Z
iso8601: 2001-12-14t21:59:43.10-05:00
spaced: 2001-12-14 21:59:43.10 -5
date: 2002-12-14

И специальные числовые значения:

negative infinity: -.inf
not a number: .NaN

С помощью приведенных ниже тегов можно поддерживать еще больше типов данных, специфичных для приложения.

7. Юникод

Сам язык YAML может не поддерживать символы Юникода, но есть безопасные способы избежать этих данных различными способами:

unicode: "Sosa did fine.\u263A"
control: "\b1998\t1999\t2000\n"
hex esc: "\x0d\x0a is \r\n"

8. Переменные

YAML не просто статичен, вы можете определить переменные для использования в другом месте. Добавьте к значению префикс &, чтобы определить переменную и позже сослаться на нее:

default: &DEFAULT
  database_name: master
development:
  <<: *DEFAULT
  database_user: dev
production:
  <<: *DEFAULT
  database_user: live

9. Теги

Простота YAML означает, что вам не нужно указывать типы данных каждого значения. В качестве альтернативы вы можете использовать теги (с префиксом !!), чтобы указать тип значения:

not-date: !!str 2002–04–28

Это может быть расширено на ваши собственные пользовательские типы, что делает его чрезвычайно мощным для сериализации типа объекта вместе со значениями, которые его представляют:

%TAG ! tag:clarkevans.com,2002:
--- !shape
  # Use the ! handle for presenting
  # tag:clarkevans.com,2002:circle
- !circle
  center: &ORIGIN {x: 73, y: 129}
  radius: 7
- !line
  start: *ORIGIN
  finish: { x: 89, y: 102 }
- !label
  start: *ORIGIN
  color: 0xFFEEBB
  text: Pretty vector drawing.

Если основной язык и синтаксический анализатор поддерживают это, есть несколько известных тегов для представления специальных типов данных:

# Sets are represented as a mapping where each key is
# associated with a null value
--- !!set
? Mark McGwire
? Sammy Sosa
? Ken Griff
# Ordered maps are represented as a sequence of
# mappings, with each mapping having one key
--- !!omap
- Mark McGwire: 65
- Sammy Sosa: 63
- Ken Griffy: 58

10. Лучше для контроля версий

Стиль YAML изначально делает его идеальным для контроля версий, поскольку вложенные элементы представлены увеличивающимся отступом. Различия, сгенерированные из изменений YAML, очень четкие и не зависят от разных стилей кода.

А как насчет недостатков?

Я думаю, что наиболее очевидным недостатком является то, что программное обеспечение решило использовать JSON для настройки, поскольку он гораздо более широко известен, что не следует путать с «лучшим решением».

YAML не является хорошим форматом обмена. Например, из API, потому что он чувствителен к пробелам. Но он по-прежнему отлично подходит для настройки.

Если вы пишете приложение, я бы настоятельно рекомендовал вам использовать YAML. Даже не заводите меня на тему Конфигурация XML.

Первоначально опубликовано на http://elliot.land 13 февраля 2016 г.