Usar YAML con variables

¿Son posibles las variables dentro de los archivos YAML? Por ejemplo:

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

En este ejemplo, ¿cómo se puede usar en otras configuraciones? ¿Qué es la sintaxis?theme: name: default

Respuestas:6 Respuestas 6
Tiempo:hace 11 años, 10 meses
Última modificación:hace 11 meses

Solución

Tenía esta misma pregunta, y después de mucha investigación, parece que no es posible.

La respuesta de cgat está en el camino correcto, pero en realidad no se pueden concatenar referencias como esa.

Aquí hay cosas que puede hacer con «variables» en YAML (que se llaman oficialmente «anclajes de nodo» cuando los establece y «referencias» cuando los usa más tarde):

Defina un valor y use una copia exacta del mismo más adelante:

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

{ o }

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.

Para obtener más información, consulte esta sección de la página wiki sobre YAML: http://en.wikipedia.org/wiki/YAML#References

Defina un objeto y utilícelo con modificaciones más adelante:

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

Esto está tomado directamente de una gran demostración aquí: https://gist.github.com/bowsersenior/979804

Otras respuestas

Esta es una publicación antigua, pero tenía una necesidad similar y esta es la solución que se me ocurrió. Es un poco un truco, pero funciona y podría refinarse.

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

A big downside is that it builds into the yaml document a variable name (in this case, «data») that may or may not exist. Perhaps a better solution would be to use $ and then substitute it with the variable name in Ruby prior to ERB. Also, just tested using hashes2ostruct which allows data.theme.name type notation which is much easier on the eyes. All that is required is to wrap the YAML::load with this

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

Then your YAML document can look like this

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

Deja un comentario