web-dev-qa-db-ja.com

変数でYAMLを使用する

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

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

この例では、theme: name: default他の設定で使用されますか?構文は何ですか?

73
brewster

私はこれと同じ質問をしました、そして、多くの研究の後、それは不可能ですそれは不可能です

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

98
benrugg

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

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 !
42
onionpsy

これは古い記事ですが、同様のニーズがあり、これが私が思いついた解決策です。これはちょっとしたハックですが、機能し、洗練される可能性があります。

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ドキュメントに組み込むことです。おそらく、より良い解決策は、$を使用し、それをRuby ERBの前の変数名で置き換えることです。また、data.themeを許可する hashes2ostruct を使用してテストする目にははるかに簡単な.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
3
Ben

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

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

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

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

別のymlファイルで...

# boo.yml

development:
  fooz: foo

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

0
Mirv - Matt