変数でYAMLを使用する


82

YAMLファイル内の変数は可能ですか?例えば:

theme:
  name: default
  css_path: compiled/themes/$theme.name
  layout_path: themes/$theme.name

この例でtheme: name: defaultは、他の設定でどのように使用できますか?構文は何ですか?


このYAMLを解析するためにどの言語/ライブラリを使用していますか?YAMLでこれを行う標準的な方法はありませんが、ライブラリにいくつかのトリックがあるかもしれません。
Jesse Beder 2010


@CiroSantilli巴拿馬文件六四事件法轮功;; 密接に関連していますが、重複していません。標準のYAMLでは任意の変数はサポートされていませんが、YAML解析ツリーから要素全体への相互参照を利用できます。したがって、質問は少し異なります。
dreftymac 2016


回答:


107

私も同じ質問をしましたが、多くの調査の結果、それは不可能のようです。

cgatからの答えは正しい方向に進んでいますが、実際にはそのような参照を連結することはできません。

YAMLの「変数」(設定すると正式には「ノードアンカー」と呼ばれ、後で使用する場合は「参照」と呼ばれます)でできることは次のとおりです。

値を定義し、後でその正確なコピーを使用します。

default: &default_title This Post Has No Title
title: *default_title

{または}

example_post: &example
  title: My mom likes roosters
  body: Seriously, she does. And I don't know when it started.
  date: 8/18/2012
first_post: *example
second_post:
  title: whatever, etc.

詳細については、YAMLに関するwikiページの次のセクションを参照してください: http //en.wikipedia.org/wiki/YAML#References

オブジェクトを定義し、後で変更して使用します。

default: &DEFAULT
  URL:          stooges.com
  throw_pies?:  true  
  stooges:  &stooge_list
    larry:  first_stooge
    moe:    second_stooge
    curly:  third_stooge

development:
  <<: *DEFAULT
  URL:      stooges.local
  stooges: 
    shemp: fourth_stooge

test:
  <<: *DEFAULT
  URL:    test.stooges.qa
  stooges: 
    <<: *stooge_list
    shemp: fourth_stooge

これは、 https //gist.github.com/bowsersenior/979804のすばらしいデモから直接引用したものです


1
また、この質問は、本質的に重複している:stackoverflow.com/questions/2063616/...
benrugg

1
何をし<<ますか?ドキュメントでそれを見つけることができないようです。
ハイエンジェル

1
@ Hi-Angel YAMLマージキー仕様は何をするのかという質問に答え<<ますか?
dreftymac 2017年

46

いくつか検索した後、%演算子を使用するよりクリーンなソリューションを見つけました。

YAMLファイル内:

key : 'This is the foobar var : %{foobar}'

あなたのRubyコードで:

require 'yaml'

file = YAML.load_file('your_file.yml')

foobar = 'Hello World !'
content = file['key']
modified_content = content % { :foobar => foobar }

puts modified_content

そして出力は:

This is the foobar var : Hello World !

@jschorrがコメントで述べたように、Yamlファイルの値に複数の変数を追加することもできます。

Yaml:

key : 'The foo var is %{foo} and the bar var is %{bar} !'

ルビー:

# ...
foo = 'FOO'
bar = 'BAR'
# ...
modified_content = content % { :foo => foo, :bar => bar }

出力:

The foo var is FOO and the bar var is BAR !

1
素晴らしい発見; 良い点は、複数の変数も実行できることです:%{var1: 'whatever'、var2: 'anotherone'}。
jschorr 2014年

2
%Ruby文字列の演算子の詳細:ruby-doc.org/core-2.2.3/String.html#method-i-25
Trantor Liu

もう1つの方法は、yamlをロードすることです。これにより、Rubyでハッシュが得られます。ハッシュに変更を加えてから、ファイルに書き戻すことができます。
leoOrion 2018

素晴らしいもの。ReactJS + Webpack + messageformat-loader + react-message-context + YAMLソリューションでも動作します。変数を小道具として使用することは、実際には箱から出してすぐに機能しました。<Message id = {'textId'} foo = {'some text'} />
ArkadiuszLendzian20年1

3

これは古い投稿ですが、私にも同様のニーズがあり、これが私が思いついた解決策です。これは少しハックですが、機能し、改良することができます。

require 'erb'
require 'yaml'

doc = <<-EOF
  theme:
  name: default
  css_path: compiled/themes/<%= data['theme']['name'] %>
  layout_path: themes/<%= data['theme']['name'] %>
  image_path: <%= data['theme']['css_path'] %>/images
  recursive_path: <%= data['theme']['image_path'] %>/plus/one/more
EOF

data = YAML::load("---" + doc)

template = ERB.new(data.to_yaml);
str = template.result(binding)
while /<%=.*%>/.match(str) != nil
  str = ERB.new(str).result(binding)
end

puts str

大きな欠点は、存在する場合と存在しない場合がある変数名(この場合は「データ」)がyamlドキュメントに組み込まれることです。おそらく、より良い解決策は、$を使用し、ERBの前にRubyの変数名に置き換えることです。また、hashes2ostructを使用してテストしたところ、data.theme.name型の表記が非常に簡単になりました。必要なのは、YAML :: loadをこれでラップすることだけです

data = hashes2ostruct(YAML::load("---" + doc))

次に、YAMLドキュメントは次のようになります

doc = <<-EOF
  theme:
  name: default
  css_path: compiled/themes/<%= data.theme.name %>
  layout_path: themes/<%= data.theme.name %>
  image_path: <%= data.theme.css_path %>/images
  recursive_path: <%= data.theme.image_path %>/plus/one/more
EOF

1

要件が複数の変数の置換を解析し、それをハッシュ/または何かとして使用するようなものである場合は、次のようなことができます

require 'yaml'
require 'json'
yaml = YAML.load_file("xxxx.yaml")
blueprint = yaml.to_json % { var_a: "xxxx", var_b: "xxxx"}
hash = JSON.parse(blueprint)

yamlの中にこのような変数を入れるだけです

"%{var_a}"

0

Rails / ruby​​フレームワークはいくつかのテンプレートを作成できます...環境変数をロードするために頻繁に使用されます...

# fooz.yml
  foo:
    bar: <%= $ENV[:some_var] %>

YML形式はjsonのスーパーセットであり、ymlファイルを読み取るものに依存すると思うので、これがjavascriptフレームワークで機能するかどうかはわかりません。

そのようなテンプレートや読者に応じ<< >>{{ }}スタイルを使用できる場合は、その後は...

別のymlファイルで..。

# boo.yml

development:
  fooz: foo

これにより、基本的に、動的に設定されるたびに、元のファイルを参照する変数を挿入できます。読んでいると、いくつかの言語のオブジェクトとしてYMLファイルをその場で作成または開くことができ、ファイルを作成して一連のYMLファイルをチェーン書き込みしたり、動的に作成されたファイルをすべて静的にポイントしたりできることもわかりました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.