Возможны ли переменные в файлах YAML? Например:
theme:
name: default
css_path: compiled/themes/$theme.name
layout_path: themes/$theme.name
В этом примере, как theme: name: default
можно использовать в других настройках? Что такое синтаксис?
Ответ 1
У меня был такой же вопрос, и после многих исследований он выглядит как не возможно.
Ответ от cgat находится на правильном пути, но вы не можете фактически конкатенировать такие ссылки.
Вот что вы можете сделать с "переменными" в YAML (которые официально называются "node anchors", когда вы устанавливаете их и "ссылки" при их использовании позже):
Определите значение и используйте его точную копию позже:
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.
Для получения дополнительной информации см. этот раздел wiki-страницы о YAML: 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
Ответ 2
После некоторого поиска я нашел более чистое решение, использующее оператор %
.
В вашем файле 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:
Ямл:
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 !
Ответ 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 имя переменной (в данном случае "данные" ), которое может или не может существовать. Возможно, лучшим решением было бы использовать $, а затем подставить его с именем переменной в Ruby до ERB. Кроме того, просто протестирован с помощью 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