YAMLとは何か? - いつもRailsの設定ファイルで出てくるやつの正体

  • 171
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

あなたがRails触る人なら見ておきたい「体系的な」豆知識」からの派生記事です。

yamlっていったい何者

  • yaml ain't markup language の略
  • 一般的な拡張子は .yml
  • 構造化データの表現方法
  • あくまでも仕様を表すため仕様を処理する実装が別途必要
  • 以下の言語でyamlを使用した実装がサポートされている
    • Java
    • JavaScript
    • Perl
    • PHP
    • Python
    • Tcl
    • Ruby
    • XML

※なお以下の説明ではrubyを使用します。

yamlの用途を端的に

  • 各種設定ファイル
  • データの保存・シリアライゼーション用
  • データ交換用フォーマット
  • ログファイル

yamlの特徴を端的に

  • 読みやすく・書きやすく・わかりやすいという特徴がある
  • インデントを使ってデータの階層構造を表す
  • 終了タグが存在しない
  • データ構造をハッシュ・配列・スカラーの三種類で表す

※例えばこんな感じで使う

input.yml
- d1
- d2
- d3
output.rb
require 'yaml'

d = YAML.load_file('input.yml')
p d

# => ["d1", "d2", "d3"]
  • 上のやつは配列になる
  • rubyファイル内では requireをつかってyamlを導入する

yamlの書き方はよ

  • 二種類の文法を主に使用する
    • シーケンス(配列形式でデータ構造を表す)
    • マッピング(ハッシュ形式でデータ構造を表す)
  • コメントアウトはパウンド記号(#)
  • 入れ子構造はインデントで表すが留意事項が二点
    • インデントにタブ記号は使えない
    • 多くの場合インデントは空白2文字で表す

■シーケンス(配列形式)の書き方

  • シーケンス = -(空白)value
  • 空白は必須であり無いとエラーが起こる
  • 値の無い行の後に字下げを使うと入れ子構造になる
input.yml
- d1
- d2
- d3
#=> ["d1", "d2", "d3"]

- d1
-
  - x1
  - x2
- d3
#=> ["d1", ["x1", "x2"], "d3"]

■マッピング(ハッシュ形式)の書き方

  • マッピング = key:(空白)value
  • こちらも空白は必須であり無いとエラーが起こる
  • 値の無い行の後に字下げを使うと入れ子構造になる
input.yml
name : tomato
email: potato@gmail.com
#=> {"name"=>"tomato", "email"=>"potato@gmail.com"}

name  : tomato
emails:
  mainaddress: potato@gmail.com
  subaddress : jagaimo@gmail.com
#=> {"name"=>"tomato", "emails"=>{"mainaddress"=>"potato@gmail.com", "subaddress"=>"jagaimo@gmail.com"}}

■複雑なデータ構造を表したい時

  • シーケンスとマッピングはお互いに入れ子構造にできる
input.yml
# 配列の各値がハッシュ
- name : tomato
  email: tomato@gmail.com
- name : potato
  email: potato@gmail.com
#=> [{"name"=>"tomato", "email"=>"tomato@gmail.com"}, {"name"=>"potato", "email"=>"potato@gmail.com"}]

# ハッシュの各値が配列
names :
  - tomato1
  - tomato2
emails:
  - potato1@gmail.com
  - potato2@gmail.com
#=> {"names"=>["tomato1", "tomato2"], "emails"=>["potato1@gmail.com", "potato2@gmail.com"]}

■ブロックスタイルとフロースタイル

  • シーケンスとマッピングには2種類の記法がある
  • ブロックスタイル
    • これまで見てきたyaml固有の書き方
  • フロースタイル
    • rubyに似通った書き方
input.yml
# ブロックスタイル
- tomato
- potato
#=> ["tomato", "potato"]

name : apple
color: red
#=> {"name"=>"apple", "color"=>"red"}


# フロースタイル
[tomato, potato]
#=> ["tomato", "potato"]

{name: apple, color: red}
#=> {"name"=>"apple", "color"=>"red"}
  • 2種類の書き方を併用することで複雑なデータ構造を表現できる

yamlのデータ型を端的に

  • データ型は自動で認識する
  • 文字列っぽいものは文字列に、数値っぽいものは数値に
  • 文字列に型変換する時にはダブルクォーテーション(")で囲む
input.yml
str    : tomato
int    : 45
float  : 5.21
bool1  : true
bool2  : false
blank  : null
date   : 2015-7-27

#=> {"str"=>"tomato", "int"=>45, "float"=>5.21, "bool1"=>true, "bool2"=>false, "blank"=>nil, "date"=>#<Date: 2015-07-27 ((2457231j,0s,0n),+0s,2299161j)>}


to_str1: "45"
to_str2: "true"

#=> {"to_str1"=>"45", "to_str2"=>"true"}
  • 他にもキャスト(型変換)の方法はあるが詳しくは文末のリンクを参照されたい

yamlでの改行表現のバリエーション

  • yamlではテキストの改行は認識されずスペースに変換される
input.yml
doc:
  aaa
  bbb
  ccc
#=> {"doc"=>"aaa bbb ccc"}
  • 改行を認識させる方法は二種類ある

  • 大なり(>)を用いて文章最後の改行のみを認識させる方法
input.yml
doc: >
  aaa
  bbb
  ccc
#=> {"doc"=>"aaa bbb ccc\n"}

  • パイプ(|)を用いて全ての改行を認識させる方法
  • これらの文法はマッピングだけでなくシーケンスでも使える
input.yml
doc: |
  aaa
  bbb
  ccc
#=> {"doc1"=>"aaa\nbbb\nccc\n"}

- |
  aaa
  bbb
  ccc
#=> ["aaa\nbbb\nccc"]

yamlでの複数データ構造の併記方法

  • 複数データの区切りを表す方法は二種類ある
  • 例えば複数のシーケンスが意図せずひとつなぎになってしまう時に使える
input.yml
- d1
- d2
- d3

- x1
- x2
#=> ["d1", "d2", "d3", "x1", "x2"]

  • ピリオド×3つ(...)を使用して以降の読み込みを中止する場合
  • デバッグ等で以降の操作を一時的に取りやめたいときに便利
input.yml
- d1
- d2
- d3
...
- x1
- x2
#=> ["d1", "d2", "d3"]

  • ハイフン×3つ(---)を使用してデータ区切りを示す場合
  • 複数のデータのまとまりをつくることができる
  • 複数のデータを読み込む際には呼び出し方法が若干異なる
  • yamlのデータであることを示すために先頭に(---)を付与することもある
output.rb
File.open('input.yml') do |io|
  YAML.load_documents(io) do |d|
    p d
  end
end
input.yml
−−−
- d1
- d2
- d3
---
- x1
- x2
#=>
["d1", "d2", "d3"]
["x1", "x2"]

【アペンディックス】