library yaml

要約

構造化されたデータを表現するフォーマットであるYAML (YAML Ain't Markup Language) を扱うためのライブラリです。

例1: 構造化された配列

require 'yaml'

data = ["Taro san", "Jiro san", "Saburo san"]
str_r = YAML.dump(data)

str_l = <<~YAML_EOT
  ---
  - Taro san
  - Jiro san
  - Saburo san
YAML_EOT

p str_r == str_l  # => true
例2: 構造化されたハッシュ

require 'yaml'
require 'date'

str_l = <<~YAML_EOT
  Tanaka Taro: {age: 35, birthday: 1970-01-01}
  Suzuki Suneo: {
    age: 13,
    birthday: 1992-12-21
  }
YAML_EOT

str_r = {}
str_r["Tanaka Taro"] = {
  "age" => 35,
  "birthday" => Date.new(1970, 1, 1)
}
str_r["Suzuki Suneo"] = {
  "age" => 13,
  "birthday" => Date.new(1992, 12, 21)
}

p str_r == YAML.load(str_l)  # => true
例3: 構造化されたログ

require 'yaml'
require 'stringio'

strio_r = StringIO.new(<<~YAML_EOT)
  ---
  time: 2008-02-25 17:03:12 +09:00
  target: YAML
  version: 4
  log: |
    例を加えた。
    アブストラクトを修正した。
  ---
  time: 2008-02-24 17:00:35 +09:00
  target: YAML
  version: 3
  log: |
    アブストラクトを書いた。

YAML_EOT

YAML.load_stream(strio_r).sort_by{ |a| a["version"] }.each do |obj|
  puts "version %d\ntime %s\ntarget:%s\n%s\n" % obj.values_at("version", "time", "target", "log")
end

# =>
#  version 3
#  time 2008-02-24 17:00:35 +0900
#  target:YAML
#  アブストラクトを書いた。
#
#  version 4
#  time 2008-02-25 17:03:12 +0900
#  target:YAML
#  例を加えた。
#  アブストラクトを修正した。
#

バックエンドの選択

yaml ライブラリでは、以下のライブラリをバックエンドとして使用します。

タグの指定

!ruby/sym :foo などのようにタグを指定することで、読み込み時に記述した値の型を指定できます。

例:

require 'yaml'
p YAML.load(<<EOS)
---
!ruby/sym :foo
EOS
# => :foo

yaml では、Ruby 向けに以下のローカルタグを扱えます。

例:

require 'yaml'
p YAML.load(<<EOS)
---
array: !ruby/array [1, 2, 3]
hash: !ruby/hash {foo: 1, bar: 2}
regexp: !ruby/regexp /foo|bar/
range: !ruby/range 1..10
EOS
# => {"regexp"=>/foo|bar/, "hash"=>{"foo"=>1, "bar"=>2}, "array"=>[1, 2, 3], "range"=>1..10}

これらは tag:ruby.yaml.org,2002:array のように指定する事もできます。

例:

require 'yaml'
p YAML.load(<<EOS)
---
array: !tag:ruby.yaml.org,2002:array [1, 2, 3]
hash: !tag:ruby.yaml.org,2002:hash {foo: 1, bar: 2}
EOS
# => {"hash"=>{"foo"=>1, "bar"=>2}, "array"=>[1, 2, 3]}

自分で定義したクラスなどは !ruby/object:<クラス名> を指定します。なお、読み込む場合には既にそのクラスが定義済みでないと読み込めません。

また、キーと値を指定する事でインスタンス変数を代入できます。

例1:

require 'yaml'

class Foo
  def initialize
    @bar = "test"
  end
end

p YAML.load(<<EOS)
---
!ruby/object:Foo
bar: "test.modified"
EOS
# => #<Foo:0xf743f754 @bar="test.modified">

例2:

require 'yaml'

module Foo
  class Bar
  end
end

p YAML.load(<<EOS)
---
!ruby/object:Foo::Bar
EOS
# => #<Foo::Bar:0xf73907b8>

注意

無名クラスを YAML 形式に変換すると TypeError が発生します。また、 IOThread オブジェクトなどはインスタンス変数がオブジェクトの状態を保持していないため、変換はできますが、YAML.load した時に完全に復元できない事に注意してください。

標準添付の yaml 関連ライブラリには以下のようなRuby 独自の拡張、制限があります。標準添付ライブラリ以外で yaml を扱うライブラリを使用する場合などに注意してください。

参考

YAML Specification

YAML4R

Rubyist Magazine: https://magazine.rubyist.net/

その他

モジュール

YAML

YAML (YAML Ain't Markup Language) を扱うモジュールです。

サブライブラリ

yaml/dbm

DBM の値に文字列以外も格納できるように拡張するためのサブライブラリです。

yaml/store

RubyのオブジェクトをYAML形式の外部ファイルに格納するためのクラスです。