Help us understand the problem. What is going on with this article?

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

More than 5 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"]

【アペンディックス】

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away