2 ポイント 投稿者 GN⁺ 2023-09-29 | 1件のコメント | WhatsAppで共有
  • DevOpsやCI設定ではYAMLが標準のように使われているが、暗黙的な型変換やパーサー差異により、同じ設定でも予想と異なる解釈をされることがある
  • YAML 1.1では、NO070804:300666のような値が真偽値・数値・時刻・8進数に変わることがあり、文字列としての意図を明確にする必要がある
  • GitHub Actions、Kubernetes、CloudFormation、各種CIサービスの事例は、YAML構文とサービスごとの構造が繰り返しコミット、エスケープの入れ子、ばらばらなjob表現につながり得ることを示している
  • 参考リンクでは、実行可能なYAML、パーサーごとの挙動差、複数行文字列の表記、バージョン1.701.7としてパースされる問題、StrictYAMLの設計根拠をまとめている
  • Nickel、Dhall、CUE、Jsonnetのような代替案も示されているが、ページ自体が巨大な編集可能テキストフィールドのように見え、YAMLのユーザビリティを風刺する流れをそのまま続けている

DevOps設定言語としてのYAML風刺

  • YAMLはDevOps設定でよく使われるが、このページは「誰もYAMLを使いたがっていない」といった文でYAML疲れを露わにしている
  • YAMLをDevOps技術として使う理由を逆説的に列挙している
    • 常にコンパイルされ、デプロイ可能だという調子で風刺している
    • 開発中の強制的なエラー処理がなく、本番ランタイムで問題が噴き出す点を皮肉っている
    • 行番号付きのスタックトレースより「何かが壊れた」というメッセージのほうがよい、という言い方をしている
    • 新しいCIパイプラインを作るときに時間を浪費しなければならないという不満を込めている
    • Kubernetesが使っているという理由で安全な選択のように扱われる状況を風刺している
    • JSONと違ってコメントをサポートするという利点にも触れている

暗黙的な型変換が生む落とし穴

  • YAML 1.1では、NO真偽値型としてパースされることがある
    • NO: Norwayは国コードではなく、真偽値解釈の問題を引き起こす可能性がある
    • 文字列を意図しているなら、"NO"のように引用符で囲む必要がある
    • YAML 1.1仕様には、trueまたはfalseを書く方法が22通りあると指摘している
  • 数値のように見える値も、パーサーによって異なる受け取り方をされることがある
    • 0708の例は、結果が[ 7, "08" ]のように異なり得ることを示している
    • Kubernetesクラスタが7つ目まではデプロイされ、8つ目で失敗する状況として風刺している
  • 時刻のように見える文字列も自動変換の対象になる
    • 04:30はユーザーが書いた時刻文字列ではなく、午前0時からの秒数である16200に変わることがある
    • 文字列を意図しているなら、!!str 04:30のように明示する必要がある
  • YAMLの8進数表記の違いも混乱を生む
    • YAML 1.1は0666表記を使う
    • YAML 1.2は0o666表記を使う
    • KubernetesがYAML 1.1を使っている点を「DevOpsの通過儀礼」のように扱っている

バージョン・SHA・文字列処理の問題

  • パッケージバージョンは浮動小数点数のようにパースされることがある
    • foo: 1.7bar: 1.70は同じバージョンのように解釈される可能性がある
    • fizz: 1.7.0buzz: 1.70.0は別のバージョン文字列として扱われることがある
  • CIで使う短いGit SHAも安全とは限らない
    • 8文字のSHAがすべて数字になることがある
    • ${GIT_SHORT_SHA}を引用符なしで入れたmy.flaky_versionは文字列ではない可能性がある
    • この値は約98%は文字列であり、"${GIT_SHORT_SHA}"のように囲めば100%文字列だと示されている
  • Rust toolchainの事例も参考リンクに含まれている

CIとインフラ設定に現れるコスト

  • GitHub Actionsを学んでいる最中、1時間に8回コミット/プッシュし、最後のコミットメッセージが“I don't really like yml”だったという事例が含まれている
  • SQLをYAMLで書くとどう見えるかを示す例もある
    • SELECTFROMWHERE EXISTSANDEQUALSLTのようなSQL構造が、YAMLの入れ子構造に変わる
    • 短いSQL表現が長く冗長なYAML形式に変わる点を風刺している
  • CIサービスごとにjobとstepの表現方法もばらばらである
    • Azure DevOpsはjobs配下にjobstepsscriptという形を使う
    • CircleCIはjobsjob1stepscheckoutrunという形を使う
    • 「未来のCIシステム」の例は、同じ作業がまた別の入れ子構造で表現され得ることを示している
  • CloudFormationでCloudWatchのDashboardBody内にSEARCH関数を入れる場合、すでにエスケープ済みの内容を再度エスケープし、JSON全体を二重引用符で閉じなければならない例が含まれている

実行可能なYAMLとパーサー差異

関連資料と代替案

ページ自体への反応

  • Redditの反応まとめでは、ページデザインまで批判の対象になっている
    • ウェブサイトが巨大な編集可能テキストフィールドだという反応がある
    • ハイパーリンクがクリックできないという反応がある
    • ページ全体のテキストを選択して削除できるので問題が解決した、という冗談がある
    • YAMLを嫌う趣旨には同意するが、ウェブサイトのデザイン判断には疑問があるという反応がある
  • 最後の文言は、ページが意図的に「YAMLと同じくらい使いやすく」作られていることを明かしている

1件のコメント

 
GN⁺ 2023-09-29
Hacker Newsのコメント
  • 私がいちばん好きな厄介ごとはこれ:
    07
    08
    結果が [ 7, "08" ] になる
    8進数と文字列に関する仮定のせい
    この仮定が、3段階下でテンプレート生成されたYAMLの中で見つかり、こちらの k8sクラスタ全体の障害につながった。ただし壊れたのは 08 クラスタだけ。前の7つは問題なく動いていた

    • このWebサイトを作った者です。これ、プルリクエストで送ってくれるとうれしい
    • くそ、最近の開発者の大半は8進数や 0 プレフィックスで書く 8進数の数値リテラルを知らなそう
      このコメントを見て笑ったけど、2023年に設定ファイルで8進数を使う人がほとんどいないことを考えると、こういう挙動や仮定は筋が通らない。16進数ならまだしも、10進数は当然として、8進数はちょっとひどい
    • これがどうして正しい挙動になり得るのか理解できない
    • その仮定を「発見した」というのは、仕様を読んだのではなく、挙動を知っていると思い込んで使い始めたという意味?
      それを生成した側は、明らかにライブラリでデータをシリアライズしていなかったのだろう。ライブラリを使っていれば、型を正しい形式に変換していたはずだから
  • YAMLには問題が多いが、本当の核心的な問題は設定の中にロジックを入れようとすることにあると思う
    YAMLはデータだけに使い、ロジックに使わないなら、人間が読み書きしやすいデータ形式の1つだ
    CI/CDには常にある程度のロジックがあり、純粋なYAMLだけで終わることはほとんどなく、奇妙なテンプレートまで混ざる。いっそ本物のプログラミング言語向けに本物のAPIを提供してくれればいいのにと思う

    • それはYAMLの問題というより、YAMLの誤用に近い。偶発的なチューリング完全性はどこでも問題になる
      15年前にXMLベースのAntを使っていたときも同じ問題があり、それはXMLのせいではなかった
      YAMLの主な問題は型安全性の不足だと思う。誤ったインデント、キーのタイプミス、ブール値としてパースされる文字列などだ
      それ以外は簡潔で、他の形式より構文上のノイズがずっと少ないので、良い形式だと思っている。だから人々が型安全なYAMLを使い、こうした問題について即座に明確なエラーメッセージを受け取れるように、https://github.com/crdoconnor/strictyamlを作った
    • 私の経験では、言語ができることが多いほど、人々はそれをより複雑な形で使うようになる
      必要だと思って抽象化を持ち込むからだ。だから設定形式としてチューリング完全なプログラミング言語を使うことは常に避けている
      AWS CDKをJavaScriptデバッガで1行ずつ追いながら何時間も費やしたことがある。単純で愚直なyaml/Json/何らかのファイルだったなら、そんな問題はなかったはずだ。小さなプロジェクトで、複雑さは必要なかった
      だからJSツールの設定でも、JSよりJSONを好む。webpackの設定がぐちゃぐちゃになる理由もここにある。本物の言語を使えるようになると、人々の「DRYセンサー」が作動して、より複雑にしてしまう
      宣言型なら標準的な慣行にも従いやすく、ツールのサポートも良くなる。package.jsonが実際にbuild.gradleのようになったら、ずっと悪くなるだろう
    • 実行可能な設定は大きな利点をもたらし得る。Pythonは明らかな選択肢だ
      「制限の強いcgroup内のPythonインタプリタでスクリプトを実行し、その結果として CONFIG という辞書が出てこなければならない」と決めればよい。ラッパーのロジックが、それを設定対象プログラムに都合のよい方法でシリアライズすればよい
    • 悪いスキーマ設計がなぜYAMLのせいで、スキーマ設計者のせいではないのか分からない
      helm の複雑さや硬直性に文句を言うのと似ている。Helmチャートは勝手に書かれるわけではない。問題を理解して実装するより、不平を言って無視するほうが簡単だからなのだと思う
    • 100%同意。人々がYAMLを嫌いだと言うとき、多くの場合、本当の意味は「YAMLでパイプラインを記述するのが嫌いだ」に近いと思う。私もその感覚は理解できる
      ファイル形式としてのYAMLには長所と短所がある。だが本当の問題は、条件文、ループ、関数、テンプレートによるクラス/サブクラスのようなものを、JSON相当のファイル形式で表現しようとすることにある
      YAMLは小さな設定には悪くない。だが何らかの制御フローが必要になった瞬間、ベンダーごとのスパゲッティへと非常に急速に膨れ上がる
  • YAML 内の Jinjaは明らかなアンチパターンだと思う
    最初から十分なプログラマビリティを設計しておらず、後になってその道を選んで成功したプロジェクトを人々がまねした結果、生まれたもののように見える
    記事では Dhall や Jsonnet といった代替案が挙がっているが、さらに2つ考えられる
    1つ目は、本物のプログラミング言語向けの設定ライブラリを作り、そのライブラリに JSON 設定ファイルを生成させること。その JSON は手で編集する対象ではなく、検査可能な成果物としてだけ扱う。ユーザーはツール支援を受けられるコード形式の設定をバージョン管理に入れることになる。サーバー上でその場の緊急修正をしにくくなるのは欠点でもあり利点でもある
    2つ目は Starlark。Bazel ビルドシステムのために最初に開発された、Python 派生の非チューリング完全言語だ。実装はいくつかあり、互換性がどの程度深いのかは分からないが、Python バインディングもある: https://github.com/caketop/python-starlark-go, https://github.com/inducer/starlark-pyo3

    • YAML 内の Jinja がアンチパターンだという点には同意するが、特にデフォルトのブロック/式文字である {%{{ がどちらも YAML の文字でもあるため、使う箇所をすべて引用符で囲まなければならないからだ
      GitHub Actions の ${{<%<< のような方式のほうがずっと良いと思う。もちろん <<: が YAML 構文だという危険はあるが、正当な Jinja ではない
      YAML の中に実行可能なものを一切入れるべきではないという意味なら、その船はもう出航してしまったと思う。人々は、リテラル部分を基本にして、ときどき実行部分だけを差し込むやり方が、ASP/JSP/PHP のようにコンテンツを作るのに向いていると知ってしまったからだ
      このスレッドで兄弟げんかのような炎上を始めたいなら HCL と for_each の話をすればよいが、少なくともここではやらないほうがよさそうだ
    • これは Amazon が CDK で選んだ道だ。ある程度は機能するが、少しでも複雑なことをしようとすると、ルーブ・ゴールドバーグ・マシンを作っている感覚が強い
      そのうちどれだけが CDK のせいで、どれだけが CloudFormation がもともといまいちなせいなのかは分からない
    • 同意する。テンプレート化された YAML を扱うのがあまりに面倒だったので、結局そのために Cels というツールを作った: https://github.com/pacha/cels
      Jsonnet と Starlark は好きだが、実際にはほとんどのユースケースで新しいプログラミング言語は必要ない。たいていは基本となるドキュメントを作り、パッチを適用して修正したいだけだ。そうすればすべてがずっと単純になる
      素の YAML を書く体験自体はそれほど悪くない。形式にはかなり疑わしい点がいくつかあるが、使えなくはない。問題は、ドキュメントを複数の環境に合わせるために追加しなければならない回避策の複雑さに現れるのだと思う
    • このせいで Ansible をまた触ることを考えるだけでも悪夢だ
      以前は YAML の代わりに使える実際の Python DSL があったと聞いたが、廃止されたようだ。なので今ではループや if-then が YAML で長々と伸びたひどい塊になり、Jinja をまったく予測不能な形で解釈する
    • jsonnet のように Starlark コードを実行して JSON や YAML を生成できるスタンドアロンツールがあるのか気になる
  • YAML自体は優れていると思う。優れていないのは、私たちがCDのデプロイ部分を難しくしすぎてしまった点だ
    Azure DevOps内の私たちの設定がものすごく良いわけではないことは認めるが、複数のチームや5〜6人の運用担当者がこうしたツールを扱わなければならない組織があるという事実には驚く。Googleのようなところはともかく、最大同時ユーザー数が5万人、たいていはそれよりずっと少ない普通のエンタープライズでは過剰に感じる
    2000年代初頭には、負荷分散やネットワーキングなどあらゆることを正社員0.25人にも満たない人員で処理していたオンプレミスのIISにエンタープライズWebアプリをデプロイするほうが、今の「モダン」な設定に同じものをデプロイするより簡単だった
    もちろんモダンなパイプラインには利点がある。「自分のマシンでは動くのに」問題をかなり乗り越え、より良い承認ゲートによって品質管理を大きく高めた。だが実際のデプロイは2023年になっても悪夢だ
    これは本物のテック企業や優秀な専任DevOpsチームがある会社のHNプログラマーにとっては問題ではないかもしれない。だが非テック系エンタープライズの世界では、CI/CDは私のキャリア上これほどひどかったことはない
    YAMLを責めることもできるし、何かをするのにあまりにも多くのYAMLが必要で、テンプレートが難しい点を責めることもできる。だが私の考えでは、技術的な問題よりも組織の問題のほうがはるかに大きい。開発者がインフラをコードで記述する仕事にならないように、CDツールはもっと自動化されるべきだ
    それが可能なのは良いことだが、現実には何百万人もの開発者に、自分がほとんど理解していないかもしれないインフラをデプロイするよう求めている。コンテナだけ渡して、ネットワーキングや「サーバー側のこと」は勝手に処理されてほしいと思わない開発者を見たことがない
    そうしないと、誰も動作の仕組みをよく知らないVNETやサブネットが大量にでき、開発者たちが/xでできることを知らないせいで組織が大金を失うことになる

    • クラウドは新しいメインフレーム
      何らかの種類の「ジョブ定義」をオフラインで書いて独占的な共有システムに投入し、キューで待ったあと、自分では制御できないシステムが生成したログファイルを受け取る。独占的なシステムのコードをワークステーション上でローカルに実行できないため、内部の反復サイクルは短くても数十分、長ければ数時間や数日になる
      プレビューや「what if」モード、「dry run」もない。「テスト」と呼んでいても、システムが1つしかないので実質的には本番環境で作業している
      本当の問題はYAMLではない。パイプラインが神のプログラミング言語でスクリプトされていても関係ないだろう
      中央のタイムシェアリング式メインフレームではなく、ワークステーションでソフトウェアを開発するやり方が大いに人気を得た理由は、内部の反復を劇的に速くし、本番環境から隔離し、制御権を開発者の手に戻したからだ
      現世代のCI/CDパイプラインは、おおむねそのすべてを元に戻している
      単一マシンのKubernetesはワークステーションベース開発の利点の大半を取り戻すが、まだ非常に新しいシステムなので成長痛が多い
      関連する問題として、1人でクリック操作で1つのアプリを運用する開発者には優れた解決策があり、数千人の開発者のために大規模な自動化を行う超巨大企業にも優れた解決策がある。だがその中間、数人のエンタープライズ開発者が数十個のアプリを管理する領域は、ただの混沌だ
    • 「自分のマシンでは動くのに」を完全に乗り越えたのかは分からない
      私のDockerイメージでは何度も問題なく動いたが、デプロイされたイメージでは壊れたことがかなりあった
      ビルドとデプロイのパイプライン全体が完全に透明で、イメージリポジトリへの完全なアクセス権があり、ビルド指示を実際に制御できて初めて乗り越えられる問題だ。これはローカルOSを制御するのと同じくらい制限が多く、別のマシンに移すとコードが壊れていた組織の数だけ失敗すると思う
    • デプロイで何が問題なのか分からない。自分が設定したものは、コミットにタグを付けてプッシュするだけで、そのコミットがデプロイされた
      どんなCI/CDシステムでも、そのように設定するのはかなり直感的に見える
  • 誰もが一つのルールだけを普遍的に尊重すれば、平和を保つ解決策があると思う: Pythonエコシステムの外ではYAMLを使わない
    そうすれば、可読性を正確性、耐久性、保守性より優先する難解なスクリプティング形式が好きな人たちは、タブ文字、緩い型、難解な構文を使い続けられる。残りの人たちはそうする必要がなくなる。Cスタイルの構文を好む人たちは正気を保てる
    問題の核心を今ようやく突いた気がする。C構文の開発者である自分にとって、構文上の空白は純粋な狂気だ。空白は情報や命令ではなく、書式だ。良い書式は助けになり有用で、優れたC構文の開発者も読みやすい書式を気にする
    PythonとYAMLでは、書式が指示情報になる。動くコードがすべて読みやすくなるという利点はある。だが、なぜコードが機能するために必ず読みやすくなければならないのか?
    YAMLのような同僚と働くところを想像すればよい。長いメッセージを送ったら「何だって? これは意味が通らない」と返ってくる。実は段落の間に空行を入れていなかったため、意味が壊れていたのだ。空行を入れ直してメッセージを送ると、ようやく読める。構文的に正しい書式がなければ、送った情報は無意味だったということだ

    • ソフトウェアとしてのコードのもう一つの目的は、実行可能であることに加えて読めることでもある
      書式を整える方法は無数にあり、私は人がコードを書くときにリンターを使うのを好む。できれば自分が使っているものと同じリンターだとなおよい
      そうした言語は標準的な構文構造を強制する。読みにくいコードを書ける方法が減るので、良いことだ
    • 通常、意味のある空白は哲学的、あるいは宗教的な問題だと見なされる。好きな人もいれば嫌いな人もいて、どちらも自分の好みを合理化するが、結局は強い嗜好の問題だ、という具合だ
      しかし今では、その違いは哲学ではなくツールの問題だと思うようになった。たとえばテキストエディタやメールソフトなど、意味のある空白をうまくサポートするツールもあれば、そうでないツールもある
      私が使うテキストエディタはすべて、スペースとタブ文字を表示するよう設定してあり、両者を異なる形で見せる。たいていは薄い点と薄いダッシュのような形だ。慣れているのでまったく気にならない
      私の見方では、コードは任意のテキストではない。本には使わない等幅フォントを使い、色で構文を区別する。空白を見えるようにしない理由もない
      それでも意味のある空白がない言語のほうを好みはするが、そういう言語を嫌ってはいない。私にとってはまったく問題にならない
      だが、お気に入りのツールが意味のある空白をうまくサポートしていなかったり、空白を可視化しなかったり、さらには可変幅フォントでコーディングしていたりするなら、意味のある空白を激しく嫌い、純粋な狂気と見るしかない
    • C出身なので、私も空白は情報や命令ではないという同じ考えを持っていた。Python初期には、そのせいで少し見下してもいた
      考えを変えたきっかけは、意外にもCoffeeScriptを使ったことだった。JavaScriptはあまり好きではないが、CoffeeScriptを使う感覚はCrockfordのThe Good Partsを洗練させたようなものだった。悪い部分をうっかり作り込むことができなかった
      さらに、インデントがコードになる方式はかなり快適だった。唯一の不便は、Viで開き波括弧や閉じ波括弧に対して%を押し、ブロックの反対側の端を見つけられない点だ。逆に、インデントのおかげでコードが変に見えるときは、実際に変な場合が多かった
      それでもPythonはまだあまり学んでいない。最近はTypeScriptを使っているが、いつかCoffeeTypeScriptが出るなら……
    • TOMLは標準ライブラリにあるのにYAMLはないというのは少し変だ。そしてTOMLは不格好だ
    • Kubernetesコミュニティが興味深そうな目で見ている
  • そこで自分でBCLという形式を作り始めた: https://github.com/wkhere/bcl
    すべてのYAMLユースケースにすぐ役立つわけではないだろうが、少なくともTerraformのようなスタイルでリソースを定義する、より良い方法にはなり得る。実際、社内プロジェクトの一つでHCLの代替としてすでに役立っており、それが作る最後の動機だった
    もっと大きく見ると、KubernetesでYAMLが至るところにある問題をどう助けられるかは分からない。私の$daily_job問題の半分以上は、複数の出所から最終的なHelmチャートを組み合わせる作業があまりにも粗雑なことにある
    Helmが本質的に悪いツールだとか、私の会社がHelmをかなり悪い形で選んだという意味ではない。皆が状況を考慮して最善を尽くしていると思う
    だが、意味のある空白を持つテキストテンプレートを操作するのはあまりにもエラーが起きやすく、エラーの発見も遅すぎる。KubernetesはYAMLがどれほど素晴らしいかを証明しようとするより、Cスタイル構文ベースの独自形式を使っていたほうがずっと良かったと思う。特にYAMLは素晴らしくもない

  • これは内部プラットフォーム効果だ。アプリケーションが大きくなるほど設定も拡張され、最終的にはプログラミング言語になるが、バグが多く、仕様が不十分で、使い勝手がひどい言語になる
    設定破産を宣言して新しい設定形式を選ぶ。そして繰り返す
    もちろん形式そのものにも責任がないわけではない。柔軟であるほど、悪いプログラミング言語として再利用されやすい
    この失敗を何度も繰り返したあと、今なら基本設定にはできるだけ単純な設定形式を選ぶだろう。.iniですら強力すぎるかもしれない。より複雑な「設定」は実際のプログラミング言語、できればアプリケーションが書かれた言語に委ねる

  • 「YAMLはよくない」という例の圧倒的大多数は、妙なリテラルをすべて引用符で囲めば解決する
    YAMLがときどき腹立たしいのは確か。たとえばマップのリストはすぐに奇妙になるし、意味を持つ空白はほぼ必ずいつか足をすくってくる。とはいえ、こうした記事は好意的に見ても少し不誠実に見える

    • ところが、そうした例の中で引用符を使っているものはなく、ツールもそうしてくれない
      YAMLエコシステム全体が、値を引用符なしで書くよう促している。たいていはうまく動くが、本番環境でつまずく程度には、ときどき壊れる
  • EDNはClojureのサブセットである: https://github.com/edn-format/edn
    明確で、ストリーミング可能で、拡張可能で、空白に敏感ではない。ただし可読性のための書式慣習はある

    • リストと集合を明示的に区別するデータ形式は初めて見たが、それはよい
      しかし、リストとベクターの意味上の違いが何なのかはよく分からない。私の頭の中では、配列と連結リストはコード内のデータ構造の実装詳細であって、データ形式の違いではない
    • 代替案よりはるかによい。Clojureエコシステムの外でも使われ始めることを本当に願っている
    • 正確には、空白非依存とは言いにくい。要素の境界や区切りのために空白が必要だからだ
      それでも意味論的なインデントの悪ふざけはまったくない。カンマが空白として扱われ、不要である点は美しい
  • 学生がeラーニングプラットフォームで課題を提出すると、私たちはすべての提出物をかなり大きなXMLファイルとして受け取る
    提出物を読み込み、静的解析とサンプル実行に渡したうえで、課題ごとにすべての提出物、採点ヒント、コメントと点数入力欄などが入ったYAMLファイルを書き出す
    その後、YAMLファイルからmarkdown+判読(Pandoc)を経て、レポート、統計、フィードバックPDFを生成する
    私たちにとってYAMLはとてもよく合っている。Markdown記法で追加フィードバックを入れやすいからだ。たとえば、正しくインデントした - you missed a \NOT` here` のような形だ
    ブロックテキストの複数のエスケープ方式のおかげで、学生がさまざまなSQL区切り文字を使っても、SQLの提出物をエスケープ文字なしできれいに出力できる
    すべてプレーンテキストなのでテキストエディタだけを使い、gitに保存して採点の説明責任を確保している。すべてを機械可読な形で保管しているため、過去の提出物に新しい静的解析ツールを試すこともできる
    ただ、CIパイプラインやホームオートメーション設定もYAMLで書かなければならないとなると、その苦痛は理解できる

    • 埋め込まれたテキストのインデント除去は、おそらくYAMLが持つ最高の機能だろう
      TOMLでは、複数行文字列のインデントを諦めて可読性を下げるか、各行末にバックスラッシュを入れなければならない。どちらも理想的ではない
      そのため、Markdownや他のテキスト形式を含める必要があるDSLや設定にはYAMLがかなり向いており、TOMLのようなものより優位に立つ
      しかし、「YAML疲れ」のすべての責任を、DSLの運搬形式としてYAMLを選んだCIやDevOpsツールだけに押しつけるつもりはない。元記事がうまく整理しているように、YAML自体にも大きな問題がある
      有名な「Norway問題」はYAML 1.2で解決され、先頭の0を8進数としてパースする問題もYAML 1.2で解決された。数字、日付、時刻などに対する過剰な型強制変換は混乱を招くことがある。複数行文字列の処理モードもかなり分かりにくいことがある。安全でないシリアライズは現代的なパーサーでは問題ではないが、Ruby、Python、Javaのように動的機能を持つ古い言語でYAMLを使うときは注意が必要だ
      これらはすべて、YAML仕様そのものの問題である