Формат данных YAML чрезвычайно усложнён. Он задумывался как удобный для человека, но в стремлении к этой цели сложность настолько увеличилась, что, по моему мнению, его разработчики достигли противоположного результата. В YAML есть куча возможностей выстрелить себе в ногу, а его дружелюбие обманчиво. В этом посте я хочу продемонстрировать это на примере.

Данный пост является нытьём и он более субъективен, чем мои обычные статьи.

YAML очень, очень сложен


JSON прост. Вся спецификация JSON состоит из шести синтаксических диаграмм. Это простой формат данных с простым синтаксисом, и больше в нём нет ничего. В отличие от него, YAML сложен. Настолько сложен, что его спецификация состоит из десяти глав с разделами, пронумерованными на четыре уровня в глубину, и отдельным списком ошибок.

Спецификация JSON не разделена на версии. В 2005 году в неё внесены два изменения (удаление комментариев и добавление научной записи для чисел), но с тех пор она заморожена (уже почти два десятка лет). Спецификация YAML имеет версии. Последняя версия довольно свежая, 1.2.2 от октября 2021 года. YAML 1.2 существенно отличается от 1.1: один и тот же документ в разных версиях YAML может парситься по-разному. Ниже мы увидим много примеров этого.

JSON настолько очевиден, что Дуглас Крокфорд заявляет, что он был открыт, как явление, а не придуман. Я не нашёл никакой информации о том, сколько времени ему понадобилось на создание спецификации, но это были скорее часы, чем недели. Переход YAML с версии 1.2.1 на 1.2.2 потребовал многолетних усилий команды специалистов:

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

Более того, эта команда планирует активно развивать YAML, а не замораживать его.

При работе со столь сложным форматом, как YAML, сложно понимать все фичи и особенности его поведения. Существует целый веб-сайт, посвящённый выбору одного из 63 синтаксисов многострочных строк. Это значит, что человеку очень сложно предсказать, как спарсится конкретный документ. Чтобы подчеркнуть это, давайте рассмотрим пример.

YAML-документ из Ада


Рассмотрим следующий документ.

server_config:
  port_mapping:
    # Expose only ssh and http to the public internet.
    - 22:22
    - 80:80
    - 443:443

  serve:
    - /robots.txt
    - /favicon.ico
    - *.html
    - *.png
    - !.git  # Do not expose our Git repository to the entire world.

  geoblock_regions:
    # The legal team has not approved distribution in the Nordics yet.
    - dk
    - fi
    - is
    - no
    - se

  flush_cache:
    on: [push, memory_pressure]
    priority: background

  allow_postgres_versions:
    - 9.5.25
    - 9.6.24
    - 10.23
    - 12.13

Проанализируем его по частям и посмотрим, как эти данные преобразуются в JSON.

Шестидесятеричные числа


Давайте начнём с того, что можно найти в конфигурации среды исполнения контейнера:

port_mapping:
  - 22:22
  - 80:80
  - 443:443

{"port_mapping": [1342, "80:80", "443:443"]}

Ой, а что здесь произошло? Оказывается, числа от 0 до 59, разделённые двоеточиями — это шестидесятеричные (по основанию 60) числовые литералы. Эта загадочная фича присутствовала в YAML 1.1, но была незаметно удалена из YAML 1.2, поэтому в зависимости от версии, которую использует парсер, элемент списка спарсится как 1342 или как "22:22". Формату YAML 1.2 уже больше десяти лет, но если вы предположите, что он широко поддерживается, то ошибётесь: последняя версия libyaml на момент написания (которая, среди прочего, используется и в PyYAML) реализует YAML 1.1 и парсит 22:22 как 1342.

Якоря, псевдонимы и тэги


Следующий фрагмент на самом деле невалиден:

serve:
  - /robots.txt
  - /favicon.ico
  - *.html
  - *.png
  - !.git

YAML позволяет создать якорь добавив & и имя перед значением, а позже вы сможете ссылаться на это значение при помощи псевдонима: *, за которым следует имя. В этом случае якоря не заданы, поэтому псевдонимы недействительны. Давайте пока избавимся от них и посмотрим, что произойдёт.

serve:
  - /robots.txt
  - /favicon.ico
  - !.git

{"serve": ["/robots.txt", "/favicon.ico", ""]}

Теперь интерпретация зависит от используемого парсера. Элемент, начинающийся с ! — это тэг. Эта фича предназначена для того, чтобы позволить парсеру преобразовывать довольно ограниченные типы данных YAML в расширенные типы, которые могут существовать на языке реализации. Тэг, начинающийся с !, интерпретируется парсером по своему усмотрению, часто вызовом конструктора с соответствующим именем и передачей ему значения, следующего за тэгом. Это значит, что загрузка непроверенного YAML-документа в общем случае небезопасна, потому что может привести к исполнению произвольного кода. (В Python можно избежать этой проблемы, используя yaml.safe_load вместо yaml.load.) В приведённом выше случае PyYAML не удаётся загрузить документ, потому что она не знает тэг .git. YAML-пакет языка Go менее строг, он возвращает пустую строку.

Проблема Норвегии


Эта проблема настолько широко известна, что её назвали проблемой Норвегии:

geoblock_regions:
  - dk
  - fi
  - is
  - no
  - se

{"geoblock_regions": ["dk", "fi", "is", false, "se"]}

Что здесь делает false? Литералы off, no и n и их различные вариации с заглавным регистром (но не все!) в YAML 1.1 считаются false, а on, yes и y считаются true. В YAML 1.2 эти альтернативные написания булевых литералов больше не допускаются, но в реальном мире они встречаются столь часто, что соответствующий стандарту парсер будет испытывать трудности с чтением многих документов. Поэтому разработчики YAML-библиотеки языка Go приняли решение реализовать собственный вариант, находящийся примерно посередине между YAML 1.1 и 1.2; в зависимости от контекста парсер ведёт себя по-разному:

YAML-пакет поддерживает бОльшую часть YAML 1.2, однако сохраняет часть поведения 1.1 для обратной совместимости. Булевы литералы YAML 1.1 (yes/no, on/off) поддерживаются, если они декодируются в типизированное значение bool. В противном случае они ведут себя как строка.

Стоит заметить, что библиотека ведёт себя так только с версии 3.0.0, выпущенной в мае 2022 года. Более ранние версии ведут себя иначе.

Ключи, не являющиеся строками


В JSON ключи всегда являются строками, однако в YAML они могут любыми значениями, в том числе и булевыми.

flush_cache:
  on: [push, memory_pressure]
  priority: background

{
  "flush_cache": {
    "True": ["push", "memory_pressure"],
    "priority": "background"
  }
}

В сочетании с ранее описанной особенностью интерпретации on как булева значения это приводит к тому, что одним из ключей словаря становится true. Если это происходит, то результат зависит от языка, выполняющего преобразование в JSON. В Python это превращается в строку "True". В реальном мире ключ on встречается часто, потому что используется в GitHub Actions. Мне было очень любопытно узнать, что ищет парсер GitHub Actions внутри, "on" или true.

Случайные числа


Если оставлять строки без кавычек, они запросто могут превращаться в числа.

allow_postgres_versions:
  - 9.5.25
  - 9.6.24
  - 10.23
  - 12.13

{"allow_postgres_versions": ["9.5.25", "9.6.24", 10.23, 12.13]}

Возможно, список — это натянутый пример, но представьте, что нужно обновить файл конфигурации, в котором указано единственное значение 9.6.24, и нужно заменить его на 10.23. Вспомните ли вы, что нужно добавить кавычки? Проблема становится ещё более коварной из-за того, что многие приложения с динамической типизацией при необходимости преобразуют неявным образом число в строку, поэтому бОльшую часть времени документ будет работать нормально, однако в некоторых контекстах может ломаться. Например, следующий шаблон Jinja принимает и version: "0.0", и version: 0.0, но для первого варианта идёт только по ветви true.

{% if version %}
  Latest version: {{ version }}
{% else %}
  Version not specified
{% endif %}

Другие примеры


Это всё, что я смог уместить в один вымышленный пример. Есть и другие загадочные поведения YAML, не вошедшие в него: директивы, целочисленные значения, начинающиеся с 0 и являющиеся восьмеричными литералами (но только в YAML 1.1), ~ как альтернативное написание null и ?, добавляющий сложный ключ преобразования.

Подсветка синтаксиса вас не спасёт


Вероятно, вы заметили, что ни в одном из моих примеров не включена подсветка синтаксиса. Возможно, я несправедлив к YAML, потому что подсветка синтаксиса выделяет специальные конструкции, поэтому мы, по крайней мере, сможем видеть значения, а не обычные строки. Однако из-за множества используемых версий YAML и разных уровней изощрённости функций подсветки на это полагаться нельзя. И в данном случае я не пытаюсь придираться: Vim, генератор моего блога, GitHub и Codeberg на самом деле подсвечивали пример документа из поста каждый по-своему. Ни один из них не выделил одно и то же подмножество значений как строки!

Шаблонизация YAML — поистине ужасная идея


Надеюсь, теперь понятно, что работа с YAML, по меньшей мере, имеет свои тонкости. Ещё более тонкая тема — конкатенация и изолирование произвольных текстовых фрагментов таким образом, что результат становится валидным YAML-документом, но не тем, который вы ожидаете. Сюда же стоит добавить значимость для YAML пробелов (whitespace). В результате мы получаем формат, о сложностях шаблонизации которого создают мемы. Я искренне не понимаю, почему инструменты, основанные на такой подверженной ошибкам практике, получили столь большое внимание, несмотря на то, что существует более безопасная, простая и мощная альтернатива: генерация JSON.

Альтернативные форматы конфигураций


Я думаю, основная причина доминирования YAML, несмотря на его проблемы, заключается в том, что долгое время он был единственным жизнеспособным форматом конфигураций. Часто нам требуются списки и вложенные данные, поэтому «плоские» форматы наподобие ini исключаются. XML шумный и вручную его писать неудобно. Но самое важное, что нам нужны комментарии, а это исключает применение JSON. (Как мы говорили ранее, изначально в JSON существовали комментарии, но их удалили, потому что люди начали помещать в них директивы парсинга. Думаю, это подходящий выбор для формата сериализации, однако из-за этого JSON не подходит как язык конфигураций.) Итак, если на самом деле нам нужна модель данных JSON, только с синтаксисом, допускающим комментарии, то какие у нас есть варианты?

  • TOML — TOML во многом похож на YAML: по большей мере в нём используются те же типы данных; синтаксис не такой многословный, как в JSON; также он позволяет использовать комментарии. В отличие от YAML, в нём не так много возможностей выстрелить в ногу, потому что строки всегда заключаются в кавычки, а значит, вы не получите значения, которые выглядят как строки, но ими не являются. TOML обладает широкой поддержкой, поэтому есть вероятность, что вы сможете найти парсер TOML для своего языка программирования. Он даже есть в стандартной библиотеке Python (в отличие от YAML!). Слабое место TOML заключается в глубоко вложенных данных.
  • JSON с комментариями, JSON с запятыми и комментариями — существуют различные расширения JSON, расширяющие его как раз настолько, чтобы он стал удобным форматом конфигураций без добавления особой сложности. Наверно, самым распространённым является JSON с комментариями (JSON with comments), поскольку он используется как формат конфигураций в Visual Studio Code. Основной недостаток этих форматов в том, что они ещё не набрали популярность (пока!), потому что не так широко поддерживаются, как JSON и YAML.
  • Простое подмножество YAML — многие из проблем YAML вызваны элементами без кавычек, которые походят на строки, но ведут себя иначе. Этого легко избежать: всегда заключайте в кавычки все строки. (Опытного YAML-разработчика можно узнать по тому, что он на всякий случай закавычивает все строки.) Мы можем принять решение всегда использовать true и false вместо yes и no, держась подальше от неявных особенностей. Сложность здесь в том, что любая конструкция, не запрещённая явным образом, рано или поздно всё равно попадёт в кодовую базу, а я не знаю ни одного хорошего инструмента, способного принудительно обеспечивать применение безопасного подмножества YAML.

Генерация JSON как более совершенного YAML


Часто выбор формата зависит не от нас и приложение может принимать только YAML. Однако не всё потеряно, ведь YAML — это надмножество JSON, поэтому любой инструмент, способный создавать JSON, можно использовать для генерации YAML-документа.

Иногда изначально приложению требуется только один формат конфигурации, однако со временем может появиться много схожих строк файлов конфигурации и вам захочется передавать между ними части, а также абстрагировать повторения. Такое случается, например, с Kubernetes и GitHub Actions. Когда язык конфигураций не поддерживает абстракций, люди обычно обращаются к шаблонизации, а это плохая идея по описанным выше причинам. Лучше подойдут настоящие языки программирования, возможно, предназначенные для конкретной области. Мои любимые — это Nix и Python:

  • Nix — это язык, используемый менеджером пакетов Nix. Он был создан для написания определений пакетов, однако достаточно хорошо работает в качестве формата конфигураций (и на самом деле используется для конфигурирования NixOS). Благодаря функциям, привязкам let и интерполяции строк он является мощным инструментом для абстрагирования повторяющейся конфигурации. Его синтаксис столь же легковесен, как и у TOML, и он может выполнять экспорт в JSON или XML. Например, он хорошо подходит для упрощения повторений в workflow-файле GitHub Actions.
  • Python — документы JSON можно с минимальной адаптацией использовать как валидные литералы Python, к тому же Python поддерживает замыкающие запятые и комментарии. Он имеет переменные и функции, мощную интерполяцию строк и встроенный json.dump. Автономный файл Python, выводящий JSON на stdout, послужит вам добрую службу!

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

  • Dhall — Dhall похож на Nix, но с типами. Он менее распространён, и лично мне имена его встроенных функций кажутся громоздкими.
  • Cue — как и Dhall, Cue интегрирует информацию о типах/схемах в формат конфигурации. Cue — надмножество JSON, но несмотря на это, файлы, в которых используются функции Cue, кажутся мне незнакомыми. Я оставлю Cue для изучения в будущем, однако пока не встречал задач, в которых Cue мог бы быть самым подходящим решением.
  • Hashicorp Configuration Language — я недостаточно долго пользовался HCL, чтобы сформировать о нём определённое мнение, но там, где я работал с ним, его потенциал абстрагирования казался более ограниченным, чем, например, у Nix.

Заключение


YAML задумывался как более дружественная для человека альтернатива JSON, но из-за всех своих особенностей он стал таким сложным форматом с таким множеством странных и неожиданных поведений, что людям сложно предсказать, как будет парситься конкретный YAML-документ. Если вам нужен формат конфигураций, то TOML — это дружественный формат без выстрелов в ногу, присущих YAML. В случаях, когда вы вынуждены пользоваться YAML, жизнеспособным решением будет генерация JSON из более подходящего языка. Генерация JSON также открывает возможности для абстрагирования и многократного использования в той степени, которую сложно безопасно достичь шаблонизацией YAML.

Комментарии (133)


  1. nronnie
    14.01.2023 09:30
    -14

    Ну, с двоеточием, по-моему, все знают. И, к тому же, насколько я знаю, - 22:22 в любом случае не спарсится как "22:22", а даст { "22": "22" }.

    Вот про "Норвегию" не знал, поэтому автора плюсую. :)


    1. longclaps
      14.01.2023 11:11
      +4

      Кратчайший ликбез по сабжу, "Learn X in Y minutes, where X=yaml" - это yaml-документ в 200 строк.

      Про "yes/no is boolean" там есть.

      Почитайте, может еще что новое для себя узнаете )


      1. Aquahawk
        14.01.2023 11:18
        +12

        Зачем изучать сложное, если есть простое?


        1. nin-jin
          14.01.2023 11:52
          -23

          Например, формат Tree, который проще и нагляднее всех названных в статье. Изучается за пару минут. Парсер пишется за час.


          1. tempick
            14.01.2023 13:28
            +31

            Я знал, что увижу этот комментарий как только прочитал заголовок статьи


          1. ReadOnlySadUser
            14.01.2023 20:31
            +15

            Я смотрю на YAML и мне больно.

            Я смотрю на Tree и думаю, что YAML был не так уж и плох.

            P.S.

            Почему по ссылке утверждается что JSON нельзя парсить поточно? Я не знаю есть ли такие парсеры или нет, но чисто концептуально я не вижу проблем написать такой. В чем конкретно там проблема-то?


            1. Cerberuser
              14.01.2023 22:32
              +1

              Как я понял - в том, что файл в любой момент может закончиться с незакрытым объектом, и тогда весь результат разбора летит в мусор.


              1. ReadOnlySadUser
                14.01.2023 22:45
                +6

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


                1. nin-jin
                  15.01.2023 04:00
                  -2

                  yaml может содержать множество документов. Полностью полученные документы можно спокойно обрабатывать, даже если какой-то из последующих обрывается на середине.


              1. omgiafs
                15.01.2023 06:28
                +7

                И тут мне вспомнилось, как в не самой незаметной и мелкой игре Insurgency: Sandstorm не менее полугода жил баг: настройки разгрузки постоянно слетали в дефолтные, т е. настроишь для инсурга-снайпера штук 5 профилей, и для остальных ролей не меньше, а при следующей загрузке игры там пустота. Полгода так было, не меньше. Все плакали. Игра на движке UE4, файлы конфигураций в JSON. Лично я сначала написал батник, который тупо копировал JSON с сохранёнными профилями на место файла профилей перед запуском игры. Но это достало в конец, и я начал исследование проблемы: вносишь правки в профиль, закрываешь игру, копируешь файл профилей в сторону, запускаешь игру - профили слетели. Штош, и новый файл профилей в сторону. Потом просто парсишь профили - вуаля, новый профиль - просто дефолтный валидный JSON, а в твоём файле профилей оказывается незакрытой одна скобка. Ставишь скобку в нужном месте, файл скармливаешь игре - хоба, игре этот файл нравится, профили не слетают. Просто движок парсил невалидный JSON, и, напоровшись на ошибку, заменял его дефолтным валидным файлом. Написал багрепорт, через неделю поправили. При том, что я не программист и вообще в IT так и не влился.

                Полгода был в проде этот баг, Карл. О нём писали всё, включая разрабов, которые в чейнджлогах новых патчей писали, что да, мол, есть такая проблема, до сих пор не вылечили.

                После этого случая стал подозревать, что в игростудиях процент нерукожопов такой же, как везде - не более 10-15 :)


                1. mayorovp
                  15.01.2023 09:33
                  +1

                  На самом деле как только дело доходит до чего-то вспомогательного, вроде сохранения и загрузки JSON, процент "нерукожопов" там оказывается даже меньше среднего по индустрии.


              1. DarthVictor
                15.01.2023 11:07
                +3

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


            1. Aquahawk
              14.01.2023 22:34
              +3

              всё прекрасно json парсится поточно


            1. nin-jin
              15.01.2023 11:45
              -2

              Что конкретно там написано каждый может почитать сам: https://github.com/nin-jin/slides/tree/master/tree#поточная-обработка

              А Робинович вам и не такое напоёт.


              1. shai_hulud
                15.01.2023 12:59
                +1

                Там голословное уважением и ничего для подтверждения. Поточный xml используется в jabber, ничего не мешает поточно читать JSON.

                В том же JSON.NET есть JsonReader который позволяет читать по одному токену, и если надо целиком объекты, можно прочитать файл любого размера условным кодом:

                var serializer = new JsonSerializer();
                var reader = new JsonTextReader(...);
                reader.ReadStartArray();
                
                while (reader.Read() && reader.TokenType != EndArray)
                {
                    var myObject = serializer.Deserialize<MyObject>(reader);
                    ...
                }


            1. Andrey_Solomatin
              16.01.2023 03:14

              Если на главном уровне это список объектов, то парсер который выдаёт по объекту за раз волне реален и удобен. Если у вас мапа и в одном из полей огромный список, то апи не будет простым. А если у все весь файл это одна строка, то парсер подавится, хотя это уж слишком крайний случай.

              Кейс со списком на мой взгляд это самый распространённый для огромного джейсона. Хотя это случай можно заменять на формат https://jsonlines.org/ . Парсер легко делается на базе обычного парсера и читалки строк вашего языка програмирования.


          1. bromzh
            14.01.2023 22:31
            +16

            Изучается за пару минут

            ...если ты его автор.

            Мне он напоминает помесь питона и перла, причём самых плохих их сторон: вложенность через отступы (когда при копи-пасте можно потерять пробелы/табы и потом не понимать, где же уехал отступ) и обилие небуквенных символов (типа $,/,@,\) для обозначения разных структур. И в лучших традициях перловских однострочников, всё это write-only вещь.


            1. Andrey_Solomatin
              15.01.2023 00:24

              Зависит от инстирументов.

              У меня IDE вечно деформирует yaml при вставке в yaml файл.

              А вот с Питоном всё норм.


            1. nin-jin
              15.01.2023 03:56
              -9

              Не выдумывайте, при копипасте отступы никуда сами не уезжают. Пунктуация есть в любом языке. Формат tree имеет лишь один спецсимвол - \. Язык json.tree добавляет ещё 3: / для списков, *для словарей и - для комментариев. Всё.


              1. Kuch
                15.01.2023 10:47
                +3

                Вот каждый каждый каждый раз при копировании больших кусков у меня первая строка остаётся с правильным отступом, а все остальные на -1 отступ. Vs code

                Я уже просто привык и даже не замечаю, как постоянно правлю это. Но сколько раз я попадал на невалидный yaml из-за этого


                1. nin-jin
                  15.01.2023 11:51
                  -5

                  Это потому что вы вставляете в конец строки, а не в начало. Надо ставить каретку в начало, вставлять код и табом регулировать его общий уровень отступов.


                  1. Cerberuser
                    15.01.2023 13:18
                    +7

                    То есть, если не регулировать - отступы всё-таки именно что "сами уезжают"?


                  1. Kuch
                    15.01.2023 13:24

                    Блин, ну это жесть какая-то. Каждый раз на это тратить время. Мне проще выделить все последующие строки и нажать таб. Но в любом случае, без дополнительных действий просто так не вставляется


                    1. nin-jin
                      15.01.2023 13:33
                      -3

                      Вам в любом случае надо тратить время на адаптацию вставленного кода. Благо массовая регулировка отступов делается за секунду. А если вы намекаете на автоформатирование, то при разбалансировке скобочек, оно такого накреативит, что порой потом пол часа приходится исправлять.


                      1. Aldrog
                        15.01.2023 21:12

                        пол часа приходится исправлять

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


                      1. nin-jin
                        15.01.2023 21:27
                        -1

                        • Отменить форматирование со всеми правками, сделанными пока не заметил косяк.

                        • Долго искать место, где и какой не хватает скобки, долбясь глазами в кривое форматирование.


                      1. bromzh
                        16.01.2023 13:13
                        +1

                        Делать правки с пропущенной скобкой? В файле куча ошибок будет, какие правки?

                        Но вообще разговор был про блоки отступами. Не скопировал скобку - вылезет ошибка, ты быстро поправишь. Но если блоки только отступами, то никто не подсветит тебе корявый отступ. А некоторые ИДЕ ещё и форматируют при вставке, что только усугубит ситуацию.


                      1. nin-jin
                        16.01.2023 13:28
                        +3

                        От скопипащенного кода почти всегда куча ошибок, пока вы не адаптируете код к контексту.

                        Если блоки отступами, то корявость ты видишь сам, даже без подсветки.


                      1. Aldrog
                        16.01.2023 14:49

                        Если блоки отступами, то корявость ты видишь сам, даже без подсветки.

                        Но автоформатирование и подсветка синтаксиса решают описанные вами проблемы скобок. Не очень понимаю, зачем вы с этим спорите.


                      1. bromzh
                        16.01.2023 16:17

                        Я чаще копирую код из этого-же файла, где контекст уже есть. Фигня в том, что блоки отступами порождают совершенно новый класс проблем.

                        Как продолжить структуру? С какого места надо копировать и как вставлять, чтобы у child2 был свой child с именем?
                        Как продолжить структуру? С какого места надо копировать и как вставлять, чтобы у child2 был свой child с именем?

                        Такая же проблема может быть и в условном питоне, где ты вставляешь какой-нибудь блок, и код валидный, но делает не то что надо.

                        > Если блоки отступами, то корявость ты видишь сам, даже без подсветки

                        Полагаться на слабую плоть, которая может устать и не заметить косяк, когда рядом есть чудо-машина? Ну уж нет. Я что, зря деньги платил?


                      1. khajiit
                        16.01.2023 14:56

                        Делать правки с пропущенной скобкой? В файле куча ошибок будет, какие правки?

                        Вы предполагаете, что после вставки и до того момента, как выяснится, что закралась ошибка — с файлом вообще ничего никогда не происходит?
                        Очень наивно.


                        Но если блоки только отступами, то никто не подсветит тебе корявый отступ

                        Перейдите уже с notepad.exe хотя бы на sublime…


                      1. bromzh
                        16.01.2023 15:58
                        +1

                        По совету проверенных камрадов перешёл на сублайм vscode. Попробовал язык с отступами и вставку там. Хочу сделать копию child внутри ещё одного child. Но что-то никак не выходит это сделать простым копипастом. Проблема в том, что любой из вариантов после копипаста валидный, но не правильный для меня.

                        Да как тебя копировать?
                        Да как тебя копировать?

                        Попробовал поганый язык со скобками, там если что-то скопировать лишнее, почему-то сразу видно ошибку.

                        А если попробовать воссоздать проблему, аналогичную ямловской, то она почему-то не воссаздаётся. Там таких проблем нет как класс.



                      1. khajiit
                        16.01.2023 17:06
                        +2

                        Обстоятельный подход, респект.
                        В саблайме новые строки маркируются слева, рядом с номером, полоской, поэтому зрительно потерять свежую вставку довольно сложно. Есть (был для 3 точно) и плагин для маркировки несохраненных строк.


                        На первой картинке вы забываете оттабить скопированный текст, хотя на второй поставить запятую — не забываете.
                        То есть, в одном случае вы пренебрегаете форматом, в другом нет — и это вопрос лишь практики и упрямства, а не недостатка формата.


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


                        Ну и третья картинка явно иллюстрирует разное и неочевидное поведение редактора касательно отступов — тут, скорее, в багтрекер писать надо.


          1. Shannon
            15.01.2023 07:57
            +3

            По ссылке написано, что минификация или однострочная форма не предусмотрена и не нужна, и то, что с таким форматом другие форматы не нужны.
            Как подразумевается работа, например, с curl?

            curl -X POST https://site -d {"login":"login","password":"pwd"}' -H 'Content-Type: application/json'



    1. dolfinus
      14.01.2023 12:27
      +7

      Нет, для того, чтобы 22 считался ключом, после двоеточия должен быть пробел


      1. pfffffffffffff
        14.01.2023 13:15
        -7

        А его заметно блин в редакторе???????


        1. Revertis
          14.01.2023 13:52
          +5

          Если не заметно, то надо менять либо редактор, либо мозг.


          1. pfffffffffffff
            14.01.2023 18:54
            -7

            Либо формат на не yaml умник


      1. nronnie
        14.01.2023 13:44
        +9

        Буду знать, но я просто всегда если в "строке" есть двоеточие, то беру её в кавычки давно уже на автомате.

        До сих пор никаких фатальных проблем с YAML лично не встречал, хотя регулярно с ним работаю. Формат, понятно, весьма расплывчатый, но говорить, что это прямо "ад" это слишком сильно. Расплывчатость формата можно считать данью некоторому удобству. Никто ведь не говорит, что JavaScript это ад только из-за того что там ; опциональна. Или что PowerShell это ад, потому что в одних случаях можно просто перенести строку, а в других случаях нужен обратный апостроф, в одних случаях можно задать массив просто как 1, 2, 3, а в других нужен полный синтаксис @(1, 2, 3) (и кавычки, к слову, там тоже "опционально опциональны" :). В большинстве случаев везде работает простое правило "сомневаешься - не сокращай". Поставь просто лишние кавычки, скобки, точку с запятой и т.п.


      1. mayorovp
        15.01.2023 09:35
        +1

        Тоже неинтуитивное поведение, кстати. В большинстве языков пробел возле спецсимвола считается незначимым.


    1. Siddthartha
      14.01.2023 12:52
      +5

      первый раз слышу, хотя годами работаю с docker-compose.yml


      1. nronnie
        14.01.2023 13:10
        +19

        В docker-compоse как раз даже в документации есть, что ports: надо все в кавычки брать и сказано почему.


    1. Wesha
      15.01.2023 08:41
      +4

      Всю жизнь говорил: умолчания — зло. Хочешь строковое значение — не выйоживайся и не экономь два байта, обрами кавычками.


  1. identw
    14.01.2023 10:15
    +15

    Вы перечислили DHall, cue, HCL. Но пропустили достаточно популярный jsonnet. Который точно также работает со структурами данных, вместо того чтобы шаблонизиоровать текст, и на мой взгляд мощнее перечисленных.

    А вот шаблонить ямл как текст, как делает helm это конечно дичь. Я тоже в шоке что это обрело такую популярность.

    А по поводу самого yaml. Да есть странности. Но я вот за всю практику (8 лет примерно) никогда не попадал на описанные проблемы. Всегда если сомневался просто использовал кавычки. Мне его читать удобнее, поэтому конфигам на ямле я рад. А вот указанные toml и xml мне читать гораздо сложнее, томл со средней и большой вложенностью совсем не в читаемую кашу превращается. Конечно наверное с большой вложенностью все форматы не читаемы для человека. А вот при умеренной вложенности, на мой взгляд yaml удобнее всего читать. IMHO

    Возможно дело ещё в том, что я кроме случаев использования helm не шаблоню ямл, а в большинстве случаев генерирую его программно. А если пишу или правлю руками, то использую кавычки почти всегда когда точно не уверен. Простые правила, но видимо благодаря ним я до сих пор не испытываю ненависти к ямлу, хотя от коллег часто слышу.


  1. Aquahawk
    14.01.2023 10:16
    +94

    Наконец кто-то это сказал вслух. Yaml это исчадие ада, не читаемое, не удобное, но обросшее мифами, что оно якобы читаемое и удобное. Я не знаю насколько у людей должна отсутствовать собственная точка зрения, когда им показывают откровенно плохую вещь и говорят что она хорошая, потому, что её автор написал, что она хорошая и кто-то на конференции тоже сказал, что это хорошо. Нет это плохо. Это было очевидно для меня с момента его появления, я избегаю его везде, но объяснять людям верующим в прекрасные технологии, что эти технологии дерьмо нет накакого желания, вера аргументами не бьётся. И чем больше я вижу как со временем мои предположения оказываются верными, тем больше я доверяю себе, а не докладчику со смузи на очередной модной конференции, у которого из аргументов только awsome, flexible, designed for humans


    1. Revertis
      14.01.2023 13:55
      +7

      Я не знаю насколько у людей должна отсутствовать собственная точка зрения, когда им показывают откровенно плохую вещь и говорят что она хорошая, потому, что её автор написал, что она хорошая и кто-то на конференции тоже сказал, что это хорошо.

      Сразу священными писаниями запахло :))


      1. Aquahawk
        14.01.2023 14:14
        +8

        Я уже давно смотрю на технологии с точки зрения веры и религии. И у молодых программистов это сейчас кажется развито больше чем раньше, просто нужно это учитывать, сложность технологий растёт, необходимость делать выбор в ограниченные сроки без полного понимания остаётся, да еще и в пиар некоторые техи умеют лучше чем другие. Но вообще, как только ты предагаешь опцию про которую никто никогда не говорил на конференциях и не писал статей, сразу вопрос, а почему бы не поступить как вот там дядя говорил?


        1. Revertis
          14.01.2023 15:14

          Да, всё так, это апелляция к авторитету.


          1. Aquahawk
            14.01.2023 15:27
            +3

            С одной стороны да, а с другой меня всегда можно обвинить в https://ru.m.wikipedia.org/wiki/Склонность_к_подтверждению_своей_точки_зрения И простого решения кто прав неи. Все эти термины всегда обоюдоостры и играясь с ними можно вывернуть всё как угодно, всегда нужно видеть людей, их задачи и мысли, а не паттерны поведения.

            Хотя я нашёл хак, как побеждать в апелляции к авторитету, например выступить на конференции и в споре ссылаться на свой доклад, тогда некоторых отпускает и они начинают разумно общаться не боясь что они сейчас, о боже, сделают что-то, что авторитетом не одобрено.


            1. ReadOnlySadUser
              14.01.2023 20:38
              +1

              Меня лично отпустило, полосе того, как я пару раз особо не думая, вернувшись с конференции попытался на чистой инициативе затащить кое какие плюшки в проект)

              В общем, оба раза закончилось это дело полным крахом, так что теперь я 7 раз думаю, а потом делаю. Но как мне кажется, это обычный нормальный здоровый путь из джуна в сеньоры, а потом и на пенсию)


              1. Aquahawk
                14.01.2023 20:44
                +2

                Ну вот про пенсию тоже верно подмечено, и хочется не быть старпёром, а иногда такую ересь предлагают, что хоть вешайся. Но новые крутые штуки безусловно есть, особенно отметил бы прогресс в языках, typescript и rust показали как можно хорошо подумать, и сделать крутую вещь. А то, что coffeescript и ruby умерли, хотя хайпа в своё время подняли море, говорит о том что нужно подождать буквально лет 5 и ересь проветрится.


                1. ReadOnlySadUser
                  14.01.2023 20:50
                  +3

                  Я согласен с тем, что в Rust есть крутые идеи и процессе изучения у меня было ощущение, что наконец-то придумали "С++ здорового человека". И всё же попытки написать на нем что-то более или менее серьезное привели меня к мысли, что как-то не очень дружественен язык. В общем, удовольствия не получил, вернулся в свой С++ мирок и черпаю из Rust иногда вдохновение)

                  А вот про typescript согласен. При условии опыта работы с типизированными языками, typescript после JavaScript как глоток свежей воды в жаркий день)


                  1. Aquahawk
                    14.01.2023 20:52
                    +6

                    Rust - концепт который показал, что так можно было. Я уверен что будущее системного программирования либо за тотальной переработкой раста или за его идеологическим наследником.


                    1. ReadOnlySadUser
                      14.01.2023 20:57
                      +1

                      Мелькал Carbon не так давно на какой-то конфе) Чисто концептуально он мне понравился больше Rust, я бы поставил на него)


                      1. AnthonyMikh
                        15.01.2023 18:54
                        +5

                        В FAQ Carbon прямым текстом написано If you can use Rust, ignore Carbon


                      1. ReadOnlySadUser
                        16.01.2023 09:35

                        Вопрос не в том, что там написано, а что в итоге взлетит в массах.

                        И пока что Carbon выглядит как Kotlin для С++. И мне это нравится. А как выглядит Rust - не уверен. Концептуально Rust классный, я даже когда-то тут сам топил за него а каждом комментарии, но последнее время сомнения меня терзают.


                  1. rmrfchik
                    16.01.2023 14:31

                    Я вижу у раста несколько категории вещей, которые сделаны круто.

                    1. Управление памятью. Они первые, кто сделал то, что сделал и понять, насколько это круто-правильно и как можно было бы сделать по другому пока сложно. Нужны исследования и новые языки с другими попытками сделать так же, но по другому.

                    2. Система типов. Божечки, наконец-то не стали копировать ООП, дак-тайпинг или, прости лямбда, прототипинг. Сели, подумали и взяли хорошее из истории. Где-то получилось не очень, но в целом достойно твёрдой пятёрки и даже с плюсом.

                    3. Тулинг. Прям молодцы, что тулинг это для них одна из первоочередных задач.

                    Вот для понимания управления памятью нужно менять мозг, а за всё остальное рукоплещу.


                    1. Wesha
                      17.01.2023 07:47

                      Управление памятью. Они первые, кто сделал то, что сделал и понять, насколько это круто-правильно и как можно было бы сделать по другому пока сложно.

                      А вот с этого момента поподробнее можно? Интересно же.

                      наконец-то не стали копировать ООП, дак-тайпинг или, прости лямбда, прототипинг. Сели, подумали и взяли хорошее из истории.

                      И с этого тоже.


      1. pfffffffffffff
        14.01.2023 18:56
        -12

        Шол в жожоба адепт


    1. blind_oracle
      14.01.2023 20:18
      +16

      Если из YAML выкинуть всё это говно непонятное и вызывающее UB - он лучше и читаемее JSON. Я использую их для конфигов своих сервисов, проблем не испытаываю, но при этом игнориую все эти доп. фичи. Выстрелить в ногу, конечно, возможности остаются, но сильно ограничены.


      1. aamonster
        15.01.2023 00:38
        +1

        Линтер пристегнули? (Благо, он тут должен примитивный получиться)


    1. caballero
      15.01.2023 02:45

      Типа как с оператором goto. Раз сам Дейкстра сказал что это зло значит зло.


      1. Aquahawk
        15.01.2023 07:11

        Однако он очень полезен при кодогенерации.


      1. AlexGluck
        15.01.2023 15:35
        +2

        По его мнению он зло, не потому что он зло, а потому, что уровень кваллификации других людей не позволяет им производительней работать с кодом.


  1. olku
    14.01.2023 10:31
    +7

    Yaml не хватило схемы вместо версии парсера, как у JSON. Большая часть проблем с валидацией бы отпала.


    1. Tony-Sol
      14.01.2023 16:12
      +2

      так ведь для yaml так же есть схемы


      1. olku
        14.01.2023 21:17

        Гм. Спасибо, не знал. Наверное, используется для другого раз валидатор это проблема и со схемой?


  1. CodeRush
    14.01.2023 10:42
    +18

    Предлагаю в качестве альтернативы рассмотреть также JSON5.


  1. acc0unt
    14.01.2023 11:05
    +25

    YAML мог бы стать тем самым остро нужным "стандартом JSON с комментариями". Вместо этого он стал вот этой вот огромной химерой, которая ухитряется быть менее читаемой и интуитивной чем сам JSON, который он в теории должен был улучшить. Отвратительно.

    Вот упомянутый выше JSON5 выглядит жизнеспособным.


    1. Didimus
      14.01.2023 12:56
      +20

      Теперь у нас есть 14 стандартов (с)


    1. gudvinr
      15.01.2023 21:01
      +1

      YAML был разработан параллельно с JSON, а не как замена ему и появился примерно в то же время.
      Поэтому было бы странно, если бы он стал "стандартом JSON", не являясь основанным на JSON.
      То, что JSON документ является валидным YAML документом, было формализовано позднее, и в общем-то это заслуга простоты JSON, а не из-за того что YAML специально был придуман с оглядкой на это.


  1. Tab10id
    14.01.2023 12:16
    +9

    Оборачиваешь строки кавычками и всё становится хорошо.


  1. maeris
    14.01.2023 12:26
    +44

    Ну вот, обещали Ada, а тут Python.


  1. bozman
    14.01.2023 12:54
    +14

    Причем истоки этого кошмара — в противоречивом ТЗ. Типа, сейчас мы сделаем формат, который будет одновременно человекочитаемым, иметь произвольную древовидную структуру, типизацию на все случаи жизни... а еще модное на момент создания форматирование отступами. И многострочные строки, куда без них. На выходе естественно ужастик со слоганом "они думали, что страшнее XML ничего нет... " :)


    1. nin-jin
      14.01.2023 13:51

      Не вижу противоречий в этом ТЗ. Просто авторы ямла не справились с ним. Бывает.


      1. Aquahawk
        14.01.2023 14:15
        +5

        В поисках волшебника найдёшь сказочника. Хорошее ТЗ это не перечисление всего хорошего что сделать надо и всего плохого, что не надо.


        1. nin-jin
          14.01.2023 15:40
          -3

          Тут в комментах выложили минимум 2 успешных выполнения этого тз.


          1. bozman
            14.01.2023 22:20

            Ну "модного форматирования отсутпами" ни в одном из них нет. И нет, я не к тому, что форматировать пробельными символами плохо само по себе. Просто в сочетании с другими требованиями оно порождает YAML.


            1. nin-jin
              15.01.2023 04:04
              -1

              В обоих есть.


          1. playermet
            15.01.2023 14:31
            +1

            "Я всю ночь не спал. Не мог заснуть! Всё думал, чем у вас восьмой инженер занимаетсякто выполнил эти условия кроме Tree?" /s



      1. bozman
        14.01.2023 17:29
        +7

        Вот, например, это загадочное кастование 1:30 в 90 как раз от слишком буквально понятого человекочитания. Это ж типа чтобы человек написал полторы минуты "по человечески", а парсер считал 90 секунд по компьютерному. Вместо того чтобы либо молча интерпретировать как строку, либо упасть с ошибкой. Но это же так фу-фу, недружественно.


        1. aamonster
          15.01.2023 00:41

          При наличии типизации, кажется, было бы вполне дружественно. Но, конечно, это сделало бы синтаксис контекстно-зависимым, что тоже больно.


          1. mayorovp
            15.01.2023 09:53
            +1

            При наличии типизации лучше бы позволить преобразованию происходить по правилам типизации, а не по правилам YAML.


            Вот в том же .NET промежуток времени хранится в TimeSpan. Какой смысл в преобразовании строки в число перед преобразованием в TimeSpan?


            1. aamonster
              15.01.2023 12:09

              Разумеется!


  1. miga
    14.01.2023 13:02
    +6

    томл вместо ямла - это такое лекарство, которое хуже болезни, как виндовые ини-файл, только более прОклято.

    rule of thumb для ямла очень прост - не злоупотребляйте опциональностью кавычек для строк и используйте { } если не уверены в синтаксисе мап/списков.


    1. dpytaylo
      14.01.2023 13:16
      +8

      Я использовал TOML в конфигах раста, и никаких проблем с его прочтением/написанием не было. Главное же, не использовать его там, где будет большая вложенность.


      1. blind_oracle
        14.01.2023 20:20
        +2

        Даже 2-3 уровня вложенности в TOML уже вызывают боль. Поэтому уехал на YAML без всего этого ужаса из статьи.


  1. sophist
    14.01.2023 13:14
    +2

    NestedText, кажется, нигде не упоминался.


  1. DirectoriX
    14.01.2023 14:01
    +6

    Для меня радость от чтения/написания YAML закончилась в тот момент, когда оказалось что массивы в нём странненькие.
    Непустой массив: после названия ставим двоеточие, а затем на каждой строке увеличиваем отступ и перед значением ставим маркер - :

    nonempty_arr:
      - val1
      - val2
    Пустой массив: после названия ставим двоеточие и [], иначе утиностипизирует в null:
    empty_arr: []

    Да, я понимаю, что массивы можно писать и в одну строку, тогда как раз и будут нужны эти квадратные скобки:
    nonempty_arr2: [val1, val2]

    Но почему-то именно непустое объявление пустого массива меня сломало. С тех пор если я выбираю формат конфигов — то только pretty-printed JSON.


    1. Mingun
      14.01.2023 14:09
      +2

      И как там, в pretty-printed JSON, непустое объявление пустого массива (а также объекта и строки) вас не смущает? Странно, что именно это вас «сломало».


      1. NekoiNemo
        14.01.2023 14:39
        +1

        А можно с примером что именно должно в нем смущать?


        1. Mingun
          14.01.2023 15:13

          Пример смотрите в комментарии выше (на который я отвечал).


          1. NekoiNemo
            14.01.2023 15:26

            В комментарии DirectoriX не было примера такого массив в pretty-printed JSON. И, если я правильно понял что "непустое объявление пустого массива" означает необходимость писать "[]"... То что именно должно в этом смущать?

            В JSON как и во всех нормальных форматах, есть синтаксис, которому нужно следовать независимо от того пустой массив или нет.

            В YAML же, синтаксиса для массивов 2 (как минимум). при этом один синтаксис используется для массивов простых объектов И позволяет объявлять пустой массив, а второй синтаксис позволяет делать массивы сложных обхектов, НО не позволяет объявлять пустой массив. Что приводит к интересным моментам как, например, невозможность просто удалить строку с последним элементом массива (т.к. это сделает этот ключ равным null, ан е пустому массиву) и вместо этого необходимость переписать этот массив на однострочный синтаксис. А когда потом потребуется снова добавить значение - переписать обратно.

            Такая несогласованность не может не "ломать" разработчика привыкшего к "форматам трезвого человека". А вот в JSON я что-то подобных проблем не припомню, отсюда и просьба привести пример.


            1. Mingun
              14.01.2023 15:34
              +1

              И, если я правильно понял что "непустое объявление пустого массива" означает необходимость писать "[]"...

              О том и речь. Но комментатора выше это смутило настолько, что он решил отказаться от yaml в пользу pretty-printed JSON, при том, что он от такого перехода вообще ничего не выиграл, ведь ровно то, что его «смутило» в yaml, присутствует и в pretty-printed JSON, только yaml, в отличие от этого, предлагает более удобный синтаксис в определённых ситуациях, а pretty-printed JSON — нет.


              1. dopusteam
                14.01.2023 15:40
                +4

                Есши перечитаете, то поймете, что комментатора выше смутило не просто [] для пустого массива, а слишком сильная разница в описании пустого массива и не пустого массива


                1. Mingun
                  14.01.2023 16:00
                  +2

                  Разницы никакой. Массив можно описывать либо «со скобками», либо «с отступами». Не нравится второй вариант — всегда используйте первый, в чём проблема? Да, второй вариант не покрывает всех возможных вариантов задания массивов, но такова плата за удобство. Кроме того, пустые массивы в реальной жизни встречаются кратно реже заполненных, так что и определяющим фактором в отказе от yaml этот факт тоже выглядит крайне странно.


            1. nin-jin
              14.01.2023 15:45
              -2

              В JSON недопустима висячая пунктуация, так что добавление/удаление последнего элемента списка при многострочном форматировании приводит к необходимости менять предыдущий элемент.


              1. NekoiNemo
                14.01.2023 15:59
                +7

                Под "последним" я подразумевал "последний оставшийся. Т.е.

                "array": [
                 {"foo": 1}
                ]

                "array": [
                ]

                А вот в YAML удалив последний элемент из

                array:
                  -foo: 1

                мы получим

                array:

                что есть null а не пустой массив. И вместо этого нужно переключится на другой синтаксис массива

                array: []

                И когда после этого требуется добавить значение обратно - в JSON все так же логично и consistent, в вот в YAML мы не можем в этот пустой массив добавить новый `foo: 2` - для этого нужно переключаться обратно на многострочный синтаксис массива.

                Так понятнее?


              1. PrinceKorwin
                14.01.2023 17:01
                -2

                Это не очень большая проблема. Элементы массива можно описывать так:

                "arr": [

                1

                , 2

                , 3

                ]

                Тогда при удалении последнего элемента массива не нужно трогать предыдущую строку.


                1. khajiit
                  14.01.2023 17:19
                  +1

                  Осталось только сделать что-то с этой передней запятой…


                1. czz
                  14.01.2023 17:25
                  +7

                  Зато нужно при удалении первого


    1. nin-jin
      14.01.2023 15:42

      Многострочный текст в pretty-printed JSON особенно хорош.


    1. nronnie
      15.01.2023 20:21
      +1

      Тут, понимаете, скорее всего недоработка самого приложения. Если оно читает конфиг, который пишут руками (а YAML практически только для этого и используется), то оно должно в той или иной степени нормально обрабатывать различные "вольности" в этом конфиге, как, например, использовать разумное значение по умолчанию вместо пропущеного. В данном случае, лично я, даже не задумывась, в самом приложении просто сразу заменял бы null на пустой массив.


  1. staticmain
    14.01.2023 14:21
    +5

    Если нам в JSON нужны комментарии, то мы используем в ванильном JSON следующие конструкции:

    Либо

    {
        "#01" : "Перечисляет возможные фичи, доступные для этого узла",
        "#02" : "Выключенное значение можно обозначить как false,",
        "#03" : "или не указывать его вовсе",
        "features" : {
            "#01" : "Включена ли TMS",
            "tms" : true,
    
            "#11" : "Использует ли узел функциональность корзины", 
            "#12" : "Её можно безопасно отключить, если не хватает места",
            "recycle_bin" : false
        }
    }

    либо

    {
        "_comment_01" : "Перечисляет возможные фичи, доступные для этого узла",
        "_comment_02" : "Выключенное значение можно обозначить как false,",
        "_comment_03" : "или не указывать его вовсе",
        "features" : {
            "_comment_01" : "Включена ли TMS",
            "tms" : true,
    
            "_comment_10" : "Использует ли узел функциональность корзины", 
            "_comment_11" : "Её можно безопасно отключить, если не хватает места",
            "recycle_bin" : false
        }
    }

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

    {
        "" : "Перечисляет возможные фичи, доступные для этого узла",
        "" : "Выключенное значение можно обозначить как false,",
        "" : "или не указывать его вовсе",
        "features" : {
            "" : "Включена ли TMS",
            "tms" : true,
    
            "" : "Использует ли узел функциональность корзины", 
            "" : "Её можно безопасно отключить, если не хватает места",
            "recycle_bin" : false
        }
    }


    1. Aquahawk
      14.01.2023 15:30
      +3

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


      1. ermouth
        14.01.2023 17:05
        +4

        Формально да, не определено, и это проблема, которая привела, например, к cve 2017-12635. Там за счёт того, что парсер на Эрланге брал первое вхождение, а js – последнее, можно было самого себя админом сделать в один post.


    1. aborouhin
      14.01.2023 16:51
      +1

      Мне кажется, такого рода комментариям (поясняющим значения настроек) самое место в description в JSON схеме. По крайней мере, если не предполагается, что JSON-файлы будут редактировать в обычных текстовых редакторах, не умеющих эти пояснения из схемы подтягивать и отображать как подсказки.

      А вот комментарии по поводу конкретных значений настройки ("тут мы поставили 3, потому что с 2 тормозит, а с 4 вылетает") да, только как-то так и писать. Но надо думать, как возможность их наличия в схему зашить...


      1. KivApple
        16.01.2023 01:19

        Можно просто использовать парсер JSON с поддержкой комментариев.


      1. KivApple
        16.01.2023 01:21
        +1

        Ещё комментарии бывают полезны для временного отключения/замены куска конфига. Например, чтобы быстро менять опции при отладке.


  1. dmi3mart
    14.01.2023 18:55
    +4

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

    Например, я работаю с October CMS, где CRUD'ы конфигурируются как раз простыми YAML-файлами. Изо дня в день приходится писать что-то вроде:

    fields:
        is_active:
            label: 'foo.catalog::lang.products.fields.is_active.label'
            type: switch
            span: full
            default: true
            comment: 'foo.catalog::lang.products.fields.is_active.comment'
        vendor_code:
            label: 'foo.catalog::lang.products.fields.vendor_code.label'
            type: text
            span: auto
        category:
            label: 'foo.catalog::lang.products.fields.category.label'
            type: relation
            nameFrom: title
            span: auto
            emptyOption: 'foo.catalog::lang.products.fields.category.empty_option'
        title:
            label: 'foo.catalog::lang.products.fields.title.label'
            type: text
            span: auto

    Аналогичный конфиг набивать руками в виде JSON или нативного массива в PHP гораздо сложнее и неудобнее. При этом за годы работы и тонны написанных конфигов я ни разу не встретился с каким-либо неочевидным поведением парсера YAML.

    Мой вывод: каждый инструмент хорош на своем месте, если ты знаешь его особенности и можешь использовать его максимально эффективно.


    1. Aquahawk
      14.01.2023 19:01
      +4

      Однака yaml часто пытаются запихать туда куда он не лезет. И вообще общий вывод опыта программирования за уже почти 20 лет, ечли это сделано чтобы было удобно писать а не читать, получается плохо. Потому что мы чаще читаем чем пишем.


      1. nronnie
        15.01.2023 20:30
        +2

        Однака yaml часто пытаются запихать туда куда он не лезет.

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


  1. semmaxim
    14.01.2023 20:29
    +7

    Я правильно понимаю, что все перечисленные проблемы - всего лишь следствие того, что строки не обязательно заключать в кавычки?


    1. Aquahawk
      14.01.2023 20:40
      +14

      Да, но авторам было лень заключать строки в кавычки потому что именно это напрягало их в json. И они объявили войну кавычкам, изобрели это и проиграли.


      1. ReadOnlySadUser
        14.01.2023 20:55
        +2

        Лень нажать одну кнопку? Воистину человеческая лень не имеет границ)


        1. Aquahawk
          14.01.2023 21:00
          +7

          Я с вами полностью согласен. Но к сожалению некоторые программисты поражены такой вредной мыслью как: "если это одинаковое действие нужно повторять, то от него нужно избавиться" Там подключается миллион мифов что повторение действий это неэффективно, что это место для ошибки и нужно сделать так чтобы никакого повторящегося действия не было. Я встречал это когда при парсинге надо проверять аргументы или еще когда нибудь когда есть похожие куски кода которые хорошо бы оставить как естьа не пытаться обобщить, не все обобщения полезны. Толи это из Совершенного кода, толи из Рефакторинга вылезло, толи ещё откуда, но такое поверие весьма распостранено, хотя по моему мнению гораздо более вредно чем полезно.


  1. skozharinov
    14.01.2023 22:37
    +1

    Хотели как лучше, а получился C++ из мира данных.


  1. i360u
    15.01.2023 02:31

    Я удивительную вещь сейчас скажу, но объектную нотацию JavaScript можно писать прямо... на языке JavaScript. Таким образом, вы получаете и комментарии, и типизацию, и валидацию и все остальное, что потом элементарно можно преобразовать в обычный JSON. А еще, это все можно подключать в виде модуля, подсвечивать, тайпчекать и линтить в IDE, использовать асинхронные API прямо внутри... И лишних кавычек в ключах нет. Тут, конечно, встанет вопрос использования JS-рантайма, если вы, к примеру, пишете на питоне, но можно воспринимать этот рантайм как своего рода парсер...


    1. Aquahawk
      15.01.2023 07:13
      +1

      я так и перешёл на то, что все конфиги у меня .js а не .json Отлично работает.


      1. i360u
        15.01.2023 15:32
        -2

        Ага, еще и изоморфные конфиги отлично пишутся. И если использовать свежие https-импорты (на ноде), то стадию преобразования в JSON вообще можно опустить. Ну, кроме случаев, когда данные нужно парсить очень быстро, JSON.parse работает быстрее чем парсинг деклараций в js (если кто не знал).


    1. Andrey_Solomatin
      16.01.2023 03:31

      Не только JavaScript, но и в Python.

      Хотя в Python чаще немного другой подход к таким конфигам. Там просто пишется файл который присваивает нужные переменные, константами или кодом.

      Например:
      - https://docs.djangoproject.com/en/4.1/topics/settings/
      - https://www.sphinx-doc.org/en/master/usage/configuration.html


  1. DmitryKoterov
    15.01.2023 04:27
    +6

    Имхо json5 (или jsonc, не знаю точно, в чем отличие) покрывает практически все необходимости. И главное, это ведь просто литерал, который валиден в JS. Т.е. если взять какой-нибудь Prettier, отформатировать им литерал из js-файла и положить в json5-файл, то вот это он и будет один в один.

    По сравнению с json, json5 опциональны кавычки для ключей словаря, есть комментарии, и завершающие запятые игнорируются. Парсится он так же быстро, как парсится json (если сравнивать библиотеки на C). Непонятно, почему бы в какой-то момент просто не взять и не сделать в json-парсерах дефолтную поддержку json5, это ведь ничего не сломает.


    1. SerafimArts
      15.01.2023 09:37
      +2

      В json5 спеке есть всякие NaN, +Inf, -Inf, которых может не быть в некоторых языках. Поэтому просто так везде добавить поддержку не получится.


      1. mayorovp
        15.01.2023 10:07

        Если сериализацию-десериализацию производить не просто так, а с учётом схемы — проблемой это не станет.


      1. KivApple
        16.01.2023 01:25
        +4

        В каких языках нет IEEE754 и насколько они актуальны в 2023 году?


        1. SerafimArts
          16.01.2023 19:10

          Хм… Сходу могу назвать SQL, где NaN/INF хоть и могут быть, но не являются флоатами/даблами в большинстве реализаций (Ну например MySQL… Ну или PostgreSQL, где это numeric).


          Ещё ANSI C (Насколько я нагуглил). Но возможно ошибаюсь, нашёл только для C++.


          P.S. Ну я то не спорю, но мне казалось всегда, что это довольно специфичные типы, которые хоть и являются частью системы типов (потомком флоата) большинства языков, но не могут быть представлены однозначной последовательностью битов в двоичном представлении. Ну, типа, как выглядит, например, -INF в LE, чтобы его можно было записать в двоичном виде и потом прочитать на любом языке, получив тот же -INF в качестве значения флоата?


          1. Cerberuser
            17.01.2023 08:25
            +2

            Ну, типа, как выглядит, например, -INF в LE, чтобы его можно было записать в двоичном виде и потом прочитать на любом языке, получив тот же -INF в качестве значения флоата?

            А это разве не часть стандарта? Сам его текст найти в свободном доступе не удалось, но беглый гуглёж предложил вот такое описание:

            For single-precision values:

            • Positive infinity is represented by the bit pattern 7F800000

            • Negative infinity is represented by the bit pattern FF800000

            For double-precision values:

            • Positive infinity is represented by the bit pattern 7FF0000000000000

            • Negative infinity is represented by the bit pattern FFF0000000000000

            То есть, как раз вполне конкретное битовое представление.


  1. mapcuk
    16.01.2023 10:34

    Действительно, а зачем специальные форматы если можно взять какой lua или python, но чтоб все переменные были неизменяемые.


  1. belozer0
    16.01.2023 22:16
    +2

    Данный пост является нытьём и он более субъективен, чем мои обычные статьи.

    Батенька, вы не умеете ныть про ямль, давайте научу.

    Лет восемь-десять назад мне посчастливилось участвовать в локализации игры по популярному сериалу по не менее популярным книжкам.

    Моей задачей было вынуть текст на перевод и потом переведённое засунуть назад.

    То, что эти деятели писали игру на рельсах, оставим на их совести. В конце концов там есть до фига бэкэндов локализации, включая божественный геттекст. Но эти рыцари решили использовать симпл, то есть тупо ямльки. Их было в проекте что-то около 2054 штук. Валидатором (самым добрым из) признаны были валидными 2 (прописью: два блин!) из 2054. Остальными ни одного. И я руками писал парсер невалидного ямль и рассоватор обратно переведёнышей.

    Ямль идиотский формат, но люди тупее и злее.


  1. capuccio
    16.01.2023 22:16

    Был (да и есть) такой простой и хороший формат: cfg. Поддерживается стандартной библиотекой libconfig. Незаслуженно забыт и здесь никем не упомянут.