Usa YAML con variabili

Sono possibili le variabili nei file YAML? Per esempio:

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

In questo esempio, come può theme: name: default essere usato in altre impostazioni? Qual è la syntax?

Ho avuto questa stessa domanda e, dopo molte ricerche, sembra che non sia ansible .

La risposta di cgat è sulla strada giusta, ma in realtà non è ansible concatenare riferimenti come quello.

Qui ci sono cose che puoi fare con “variabili” in YAML (che sono ufficialmente chiamate “ancore di nodes” quando le imposti e “riferimenti” quando le usi in seguito):

Definire un valore e utilizzare una copia esatta di esso in un secondo momento:

 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. 

Per maggiori informazioni, vedere questa sezione della pagina wiki su YAML: http://en.wikipedia.org/wiki/YAML#References

Definisci un object e usalo con le modifiche successive:

 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 

Questo è preso direttamente da una grande demo qui: https://gist.github.com/bowsersenior/979804

Dopo qualche ricerca, ho trovato una soluzione più pulita che usa l’operatore % .

Nel tuo file YAML:

 key : 'This is the foobar var : %{foobar}' 

Nel tuo codice ruby:

 require 'yaml' file = YAML.load_file('your_file.yml') foobar = 'Hello World !' content = file['key'] modified_content = content % { :foobar => foobar } puts modified_content 

E l’output è:

 This is the foobar var : Hello World ! 

Come ha detto @jschorr nel commento, puoi anche aggiungere più variabili al valore nel file Yaml:

Yaml:

 key : 'The foo var is %{foo} and the bar var is %{bar} !' 

Rubino:

 # ... foo = 'FOO' bar = 'BAR' # ... modified_content = content % { :foo => foo, :bar => bar } 

Produzione :

 The foo var is FOO and the bar var is BAR ! 

Questo è un vecchio post, ma ho avuto una necessità simile e questa è la soluzione che ho trovato. È un po ‘un trucco, ma funziona e potrebbe essere raffinato.

 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 

Un grande svantaggio è che crea nel documento yaml un nome di variabile (in questo caso, “dati”) che può o non può esistere. Forse una soluzione migliore sarebbe usare $ e poi sostituirlo con il nome della variabile in Ruby prima di ERB. Inoltre, appena testato utilizzando hashes2ostruct che consente la notazione del tipo data.theme.name che è molto più facile per gli occhi. Tutto ciò che serve è avvolgere lo YAML :: load con questo

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

Quindi il tuo documento YAML può assomigliare a questo

 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