プログラミング初心者がアーキテクトっぽく語る

見苦しい記事も多数あるとは思いますが訂正しつつブログと共に成長していければと思います

YAML

YAMLはシステム間のデータ交換や設定ファイルに使われているデータフォーマットだ。誰でも一度は見たことがあるだろう。

YAMLJSONもただのテキストの羅列だと思っていると損をする。YAMLは豊富なデータ型やimportに相当する機能も持つ高機能なデータ構造表現方式だ。JSONではなくYAMLをあえて採用する場合にはこういったYAMLの高機能性に期待している場合もある。

こうした背景を知らないと日付型として直接JSONから取り出せるデータをわざわざ文字列として取り出してその後に日付型に変換するといった無駄な処理を実装、試験したりしかねない。また、冗長で長大な運用しにくいデータフォーマットを作成してしまうこともあるだろう。

ここではYAMLについて説明する。

JSONについてはこちらを参考にして欲しい。

architecting.hateblo.jp

基本情報

  • YAMLYAML Ain't a Markup Language
  • 最新版:1.2
  • 拡張子:yml

特徴

  • XMLと比較して「読みやすい」「書きやすい」「わかりやすい」と言われている
  • 「シーケンス」「マッピング」「スカラー (数値や文字列や真偽値)」の3つで表現する
  • インデントが重要な意味を持つ
  • インデントは空白2つで表現する(tabは利用不可)
  • コメントは#
  • JSONと同様にデータのシリアル化などで広く使われる
  • コメントが記載できること、括弧が不要なことからJSONより人間が読み書きしやいため設定ファイルなどにも使われる
  • 言語としてはRubyPythonでよく見かける

シーケンス

  • 配列、リストのこと
  • 行頭に「-」
  • 空シーケンスの下の行を半角スペースでインデントするとネスト構造になる
- a
-
  - b1
  - b2
  -
    - b3.1
- c

マッピング

  • ハッシュ、連想配列のこと
  • 「キー: 値」
  • :の後ろに半角スペースが必要
  • マッピングの下の行を半角スペースでインデントするとネスト構造になる
A: a
B:
  B1: b1
  B2: b2
  B3:
    B3.1: b3.1
C: c

配列とハッシュの組み合わせ

  • 配列の各要素にハッシュ
- name:  Taro
  drink: wine
- name:  Hanako
  drink: beer

JSONの下記の表記と同じ。

[
  {
    "name": "Taro",
    "drink": "wine"
  },
  {
    "name": "Hanako",
    "drink": "beer"
  }
]
  • ハッシュの中に配列
names:
  - Taro
  - Hanako
drink:
  - wine
  - beer

JSONの下記の表記と同じ。

{
  "names": [
    "Taro",
    "Hanako"
  ],
  "drink": [
    "wine",
    "beer"
  ]
}

スカラ

  • 以下のデータ型に対応

    • 文字列
    • 整数
    • 浮動小数
    • 真偽値 (true, yes, false, no)
    • Null値 (null, ~)
    • 日付 (yyyy-mm-dd)
    • タイムスタンプ (yyyy-mm-dd hh:mm:ss [+-]hh:mm)
  • データ型は自動で判別

  • 「’」や「”」で囲むと文字列
  • !<データ型>(例:!str)でデータ型を明示的に指定できる

複数行文字列の扱い

  • 下記のように記述すると空白で結合された1つの文字列スカラーとして認識される

text:
  abc
  def

結果

abc def
  • 「|」をつけると各行の改行が保存される
  • 「>」をつけると各行の改行が空白になる
  • 「+」をつけると最終行の改行を保存する
  • 「-」をつけると最終行の改行を保存しない

text: |-
  abc
  def

結果

abc\ndef

アンカーとエイリアス

&name(アンカー)で定義したスカラーを*name(エイリアス)で指定した箇所に挿入できる

  • シーケンスの例
- &mark hoge
- foo
- *mark

以下と同じ結果になる

- hoge
- foo
- hoge
A: &mark
   hoge
B: foo
C: *mark

以下と同じ結果になる

A: hoge
B: foo
C: hoge

マージ

マッピングまたはシーケンスでもエイリアスと同じことができる。「<<」を使用する。

common: &common
  nationality: japan

Taro:
  <<: *common
  house: tokyo

セパレータ

次のように2つのシーケンスが連続していると1つのシーケンスと見なされてしまう。

- a
- b

- c
- d

セパレータを使うことで2つのシーケンスと見なすことができる。

- a
- b
---
- c
- d

YAMLのデータであることを示すために先頭にセパレータを付与することもある。

なおピリオド 3つ(...)がある場合、以降の読み込みを中止する。


フロースタイル

  • これまで記述したようにインデントを使って構造を表す書き方を「ブロックスタイル」という。
  • 中括弧や大カッコをを使って構造を表す書き方をは「フロースタイル」という
  • ブロックスタイルとフロースタイルは混在することができる
  • フロースタイルを突き詰めていくとJSONと同じになる
  • よってYAMLのライブラリはJSONも読めることが多い

  • シーケンスは大カッコ

  • マッピングは中括弧
  • コンマ「,」のあとには半角空白を入れる
  • コロン「:」のあとには半角空白
  • ネスト可能

  • シーケンスの例

[aaa, bbb, ccc]
{ A: aaa, B: bbb, C: ccc }

練習問題

YAMLは括弧を使わないので複雑なYAMLの構造を読み取るには正しい理解と慣れが必要だ。無料の構文チェッカーやJSON変換ツールを活用するとよいだろう。

YAML
json:
  - rigid
  - better for data interchange
yaml: 
  - slim and flexible
  - better for configuration
object:
  key: value
  array:
    - null_value:
    - boolean: true
    - integer: 1
    - alias: &example aliases are like variables
    - alias: *example
paragraph: >
   Blank lines denote

   paragraph breaks
content: |-
   Or we
   can auto
   convert line breaks
   to save space
alias: &foo
  bar: baz
alias_reuse: *foo 
JSON
{
  "json": [
    "rigid",
    "better for data interchange"
  ],
  "yaml": [
    "slim and flexible",
    "better for configuration"
  ],
  "object": {
    "key": "value",
    "array": [
      {
        "null_value": null
      },
      {
        "boolean": true
      },
      {
        "integer": 1
      },
      {
        "alias": "aliases are like variables"
      },
      {
        "alias": "aliases are like variables"
      }
    ]
  },
  "paragraph": "Blank lines denote\nparagraph breaks\n",
  "content": "Or we\ncan auto\nconvert line breaks\nto save space",
  "alias": {
    "bar": "baz"
  },
  "alias_reuse": {
    "bar": "baz"
  }
}