YAMLファイルに別のYAMLファイルの値を参照、設定したい
こういうことがしたかったのですが、
# a.yml id: 1 type: foo description: baz # b.yml id: 2 type: bar description: (ここで a.yml の description の値を参照したい)
こんな風にしました。
YAML.add_domain_type(nil, "include") do |type, val| YAML.load_file("path/to/a.yml")[val] end # b.yml id: 2 type: bar description: !include "description"
最初は b.yml.erb みたいにすればまあ出来るかなと、こんな感じのことを考えましたが、後で知った上の方法に変更したのでした。
# b.yml.erb id: 2 type: bar description: <%= YAML.load_file(path)["description"] %>
2016/08/05 追記
深い階層の場合にも対応しようと思い、こうしました。
# a.yml id: 1 type: foo description: baz too: deep: key: !include "深い階層にも対応" # b.yml id: 2 type: bar description: (ここで a.yml の description の値を参照したい) too: deep: key: !include "too deep key" # 今回は space 区切りを想定した。 うっかり space が多く含まれてしまった場合にも対応している。 key: !include " too deep key " # YAML YAML.add_domain_type(nil, "include") do |type, val| y = YAML.load_file("path/to/a.yml")["some_key"] val.to_s.strip.split(/\s+/).each do |key| y = y[key] unless y.nil? end y end # ruby 2.3 の場合は Hash#dig でこう書ける YAML.add_domain_type(nil, "include") do |type, val| y = YAML.load_file("path/to/a.yml")["some_key"] y.dig(*(val.to_s.strip.split(/\s+/))) end