Подтвердить что ты не робот

Использовать YAML с переменными

Возможны ли переменные в файлах YAML? Например:

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

В этом примере, как theme: name: default можно использовать в других настройках? Что такое синтаксис?

4b9b3361

Ответ 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