2010-06-29 16 views
5

Mi piacerebbe avere un oggetto YAML fare riferimento ad un altro, in questo modo:Un oggetto YAML può riferirsi a un altro?

intro: "Hello, dear user." 

registration: $intro Thanks for registering! 

new_message: $intro You have a new message! 

La sintassi di cui sopra è solo un esempio di come potrebbe funzionare

(è anche il modo sembra funzionare in this cpan module.)

Sto usando il parser standard di ruby ​​yaml.

È possibile?

risposta

7

Alcuni oggetti YAML fanno riferimento agli altri:

irb> require 'yaml' 
#=> true 
irb> str = "hello" 
#=> "hello" 
irb> hash = { :a => str, :b => str } 
#=> {:a=>"hello", :b=>"hello"} 
irb> puts YAML.dump(hash) 
--- 
:a: hello 
:b: hello 
#=> nil 
irb> puts YAML.dump([str,str]) 
--- 
- hello 
- hello 
#=> nil 
irb> puts YAML.dump([hash,hash]) 
--- 
- &id001 
    :a: hello 
    :b: hello 
- *id001 
#=> nil 

Si noti che non sempre riutilizzare gli oggetti (la stringa è solo ripetuto), ma lo fa a volte (l'hash viene definita una volta e riutilizzato per riferimento).

YAML non supporta stringa di interpolazione - che è quello che sembra essere cercando di fare - ma non c'è ragione per cui non si poteva codificare un po 'più verboso:

intro: Hello, dear user 
registration: 
- "%s Thanks for registering!" 
- intro 
new_message: 
- "%s You have a new message!" 
- intro 

Quindi è possibile interpolare esso dopo aver caricato il YAML:

strings = YAML::load(yaml_str) 
interpolated = {} 
strings.each do |key,val| 
    if val.kind_of? Array 
    fmt, *args = *val 
    val = fmt % args.map { |arg| strings[arg] } 
    end 
    interpolated[key] = val 
end 

E questo produrrà quanto segue per interpolated:

{ 
    "intro"=>"Hello, dear user", 
    "registration"=>"Hello, dear user Thanks for registering!", 
    "new_message"=>"Hello, dear user You have a new message!" 
} 
+0

Interessante. Due domande: [1] Quindi dump non restituisce solo una stringa, ma cerca le variabili nell'ambiente di esecuzione? [2] Non sono sicuro di aver capito cosa è successo nel caso dell'hash. –

+1

@John: [1] il dump non analizza le variabili, ma cerca la ripetizione w/nell'oggetto passato. [2] in 'YAML.dump ([hash, hash])', aveva una serie di hash di simboli sulle stringhe. Nel suo controllo dell'array, ha scoperto che i due hash si riferivano allo stesso oggetto. Quindi, la prima volta che stampava l'hash, forniva un identificatore ('& id001') per quell'hash, e la seconda volta, invece di stampare di nuovo l'intera cosa, faceva riferimento a quell'identificatore (' * id001'). – rampion

+0

Capisco. Quindi questo non mi porta da nessuna parte nel mio tentativo di riutilizzare oggetti all'interno di file yaml, giusto? –

2

Piuttosto che cercare di utilizzare riferimenti impliciti nel proprio yaml, perché non si usano stringhe di sostituzione (come si mostra sopra, sono comunque necessarie le virgolette) e si sostituisce esplicitamente il contenuto di esse in fase di analisi?

+0

In questo senso, suppongo che la mia domanda sia "il parser standard YAML di Ruby lo supporta già esplicitamente?" –

Problemi correlati