LoginSignup
8
10

More than 5 years have passed since last update.

YAMLをRubyへ変換する時に困らなくなる記事

Posted at

YAMLファイル内の"<<"とか"&"の仕様を理解していなかったので、YAMLからRubyオブジェクトにどのように変換されるのかQiitaにまとめました。

YAML 1.1 構文早見表

構文は次URLのリファレンスカードが見やすいです。

このリファレンスカードからtagを除いた良く使われる構文を列挙します。

  • コレクション
    • '?' : キー
    • ':' : 値
    • '-' : 入れ子のエントリー
    • ',' : インラインのセパレーター
    • '[]' : インラインで配列
    • '{}' : インラインのマップ
    • '''' : シングルクオート。エスケープされていない値
    • '"' : ダブルクオート。エスケープされた値。※YAMLのエスケープ文字について ->(http://yaml.org/spec/current.html#id2517668)
    • '|' : ブロック
    • '>' : フォールド
    • '-' : chompする
    • '+' : chompしない
    • 1-9 : インデント数。chompと組み合わせ可 ('|2-', '>+1').
  • エイリアス
    • '&' : アンカープロパティ
    • '*' : エイリアス
  • その他
    • '#' : コメント行
    • '`@' : `と@は予約語
  • スペシャルキー

YAMLからRubyオブジェクトへの変換

コレクション

yaml
sequence: [ one, two, ]
mapping: { sky: blue, sea: green }
ruby
{
  "sequence" => [
    "one",
    "two"
  ],
   "mapping" => {
    "sky" => "blue",
    "sea" => "green"
  }
}

ブロック

yaml
block:
- one
- two : three
ruby
{"block"=>["one", {"two"=>"three"}]}
yaml
- |
 literal
- >
 folded
ruby
["literal\n", "folded\n"]

chomp

yaml
strip: |-
  text
clip: |
  text
keep: |+
  text
ruby
{"strip"=>"text", "clip"=>"text\n", "keep"=>"text\n"}

インデント数

yaml内のspace2つ
- |
  hoge
ruby
["hoge\n"]
yaml内でspace3つと指定してるけど実際には2つ
- |3
  hoge
ruby
Psych::SyntaxError: (<unknown>): did not find expected '-' indicator while parsing a block collection at line 2 column 1

アンカープロパティとエイリアス

yaml
anchored: !local &anchor value
alias: *anchor
ruby
{
  "anchored" => "value",
     "alias" => "value"
}

入れ子の関係での例

yaml
a: &a
 aa: aa
b: *a
ruby
{
  "a" => {
    "aa" => "aa"
  },
  "b" => {
    "aa" => "aa"
  }
}

コメントの記述例

yaml
# Comment only.
ruby

"=" の記述例

yaml
link with:
  - = : library1.dll
    version: 1.2
  - = : library2.dll
    version: 2.3
ruby
{
  "link with" => [
    {
            "=" => "library1.dll",
      "version" => 1.2
    },
    {
            "=" => "library2.dll",
      "version" => 2.3
    }
  ]
}

<< の記述例

マップをマージした後にエントリーを追加する例

yaml
a: &a
 aa: aa
b:
 <<: *a
 bb: bb
ruby
{
  "a" => {
    "aa" => "aa"
  },
  "b" => {
    "aa" => "aa",
    "bb" => "bb"
  }
}

リファレンス内サンプル(http://yaml.org/type/merge.html) の実行結果

yaml
- &CENTER { x: 1, y: 2 }
- &LEFT { x: 0, y: 2 }
- &BIG { r: 10 }
- &SMALL { r: 1 }

# All the following maps are equal:

- # Explicit keys
  x: 1
  y: 2
  r: 10
  label: center/big

- # Merge one map
  << : *CENTER
  r: 10
  label: center/big

- # Merge multiple maps
  << : [ *CENTER, *BIG ]
  label: center/big

- # Override
  << : [ *BIG, *LEFT, *SMALL ]
  x: 1
  label: center/big
ruby
[
  {
    "x" => 1,
    "y" => 2
  },
  {
    "x" => 0,
    "y" => 2
  },
  {
    "r" => 10
  },
  {
    "r" => 1
  },
  {
        "x" => 1,
        "y" => 2,
        "r" => 10,
    "label" => "center/big"
  },
  {
        "x" => 1,
        "y" => 2,
        "r" => 10,
    "label" => "center/big"
  },
  {
        "r" => 10,
        "x" => 1,
        "y" => 2,
    "label" => "center/big"
  },
  {
        "r" => 10,
        "x" => 1,
        "y" => 2,
    "label" => "center/big"
  }
]

参考情報

さいごに

railsの長くなったi18n(lng.yml)に困っていたのですがアンカー(&)とエイリアス(*)とマップのマージ(<<)を使ってスッキリさせることが出来ました。

何かありましたらコメント欄にお願いします。

8
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10