与variables一起使用YAML
YAML文件中的variables是可能的吗? 例如:
theme: name: default css_path: compiled/themes/$theme.name layout_path: themes/$theme.name
在这个例子中, theme: name: default
如何在其他设置中使用? 什么是语法?
我有同样的问题,经过大量的研究,看起来不可能 。
cgat的答案在正确的轨道上,但是你不能像这样实际地连接引用。
这里是你可以用YAML中的“variables”做的事情(当你设置它们时,它们被正式称为“节点锚点”,稍后使用时则是“引用”):
定义一个值并在以后使用它的精确副本:
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
经过一番search,我find了一个更清洁的解决scheme,使用%
运算符。
在你的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文件中添加多个variables:
Yaml:
key : 'The foo var is %{foo} and the bar var is %{bar} !'
ruby:
# ... foo = 'FOO' bar = 'BAR' # ... modified_content = content % { :foo => foo, :bar => bar }
输出:
The foo var is FOO and the bar var is BAR !
这是一个旧的post,但我有类似的需求,这是我想出的解决scheme。 这是一个黑客,但它的工作,可以提炼。
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文档中build立了一个variables名(在这种情况下,“数据”)可能存在也可能不存在。 也许更好的解决scheme是使用$,然后在ERB之前用Ruby中的variables名replace它。 此外,刚刚使用hashes2ostruct进行testing,它允许data.theme.nametypes表示法,眼睛上更容易。 所有需要的是用这个来包装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