Ruby
Rails
YAML

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

More than 3 years have passed since last update.

あなたが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"]


【アペンディックス】