2013-10-11 16 views
5

Ecco il mio file YAML, 'test.yml':Rubino YAML più documenti

--- 
alpha: 100.0 
beta: 200.0 
gama: 300.0 
--- 3 
... 

Il primo documento è un hash.

Il secondo documento è un numero intero.

Sto provando a caricarli in un programma Ruby come un hash e un intero.

Ecco il mio tentativo in corso:

require 'yaml' 

variables = YAML.load_file('test.yml') 
puts variables.inspect 

risposta

0

Non usare più documenti; Non sono un sostituto per la definizione di singoli elementi nei dati:

require 'yaml' 

yaml = <<EOT 
--- 
hash: 
    alpha: 100.0 
    beta: 200.0 
    gama: 300.0 
int: 3 
EOT 

YAML.load(yaml) 
# => {"hash"=>{"alpha"=>100.0, "beta"=>200.0, "gama"=>300.0}, "int"=>3} 

È possibile accedere ai contenuti assegnando YAML.load(yaml) ad una variabile:

data = YAML.load(yaml) 
data['hash'] # => {"alpha"=>100.0, "beta"=>200.0, "gama"=>300.0} 
data['int'] # => 3 

pensare in questo modo, si sta chiedendo per un oggetto di qualche tipo da YAML dopo aver analizzato il file YAML. Devi essere in grado di estrarre valori specifici da esso, quindi rendilo facile per te stesso e definisci un array o un hash che contiene ciò che vuoi, in un modo che funziona esattamente come fa il tuo cervello, entro i limiti e le specifiche di YAML.

Se ho intenzione di essere la creazione di una struttura complessa, lo faccio in Ruby prima e hanno YAML discarica il formato per me:

require 'yaml' 

data = { 
    "hash" => { 
    "alpha" => 100.0, 
    "beta" => 200.0, 
    "gama" => 300.0 
    }, 
    "int" => 3 
} 

puts data.to_yaml 

# >> --- 
# >> hash: 
# >> alpha: 100.0 
# >> beta: 200.0 
# >> gama: 300.0 
# >> int: 3 

posso mettere il codice Ruby in uno script ed eseguirlo , ad orientarli verso un file YAML:

ruby test.rb > test.yaml 

allora posso espandere la struttura:

require 'yaml' 

data = { 
    "hash" => { 
    "alpha" => 100.0, 
    "beta" => 200.0, 
    "gama" => 300.0 
    }, 
    "int" => 3, 
    "array" => %w[a b c] 
} 

puts data.to_yaml 

# >> --- 
# >> hash: 
# >> alpha: 100.0 
# >> beta: 200.0 
# >> gama: 300.0 
# >> int: 3 
# >> array: 
# >> - a 
# >> - b 
# >> - c 

Test è di andata e ritorno:

require 'yaml' 

yaml = <<EOT 
--- 
hash: 
    alpha: 100.0 
    beta: 200.0 
    gama: 300.0 
int: 3 
array: 
- a 
- b 
- c 
EOT 

YAML.load(yaml) 
# => {"hash"=>{"alpha"=>100.0, "beta"=>200.0, "gama"=>300.0}, "int"=>3, "array"=>["a", "b", "c"]} 

iterativamente fare che fino a sei a tuo agio con la sintassi YAML, allora si può costruire/modificare il file YAML a mano.

Ora, ecco come è intelligente. Le specifiche YAML supportano gli alias, che consentono di definire una variabile, quindi riutilizzarla più volte utilizzando rispettivamente & e *. Creazione di quelli a mano è un dolore quando il documento diventa grande, ma il driver YAML è intelligente e di uscita sarà per voi:

require 'yaml' 

FOO = ['foo'] 
BAR = ['bar'] 

foobar = [FOO, BAR] 

data = { 
    "foo" => FOO, 
    'bar' => BAR, 
    'foobar' => foobar, 
} 

puts data.to_yaml 


# >> --- 
# >> foo: &1 
# >> - foo 
# >> bar: &2 
# >> - bar 
# >> foobar: 
# >> - *1 
# >> - *2 

foo: &1 definisce ["foo"], e viene riutilizzato in fondo come *1.

"Yaml Cookbook at the YamlForRuby site" è un ottimo riferimento per lavorare con YAML.

+0

Ci sono uso ragionevole casi in cui si desidera utilizzare più documenti. Ad esempio un flusso di documenti. –

+0

Sì, ma nel caso dell'OP l'utilizzo di più documenti non era l'approccio giusto. Le risposte non dovrebbero risolvere il problema come richiesto, dovrebbero anche educare. Vediamo molte domande tipo [XY Problem] (http://xyproblem.info) quindi è importante anche un modo più appropriato di gestire il problema. –

+0

Certo, allora potrebbe essere utile provare a rendere la risposta un po 'più precisa facendo notare che più documenti potrebbero non essere l'approccio corretto in questo caso specifico. Sto principalmente pensando alla prima frase, che suona molto drastica. –

4

Il Tin Man è corretto che l'OP non deve utilizzare più documenti per il suo problema specifico; tuttavia, la situazione di più documenti in un flusso YAML si verifica in pratica, ad esempio quando più documenti YAML vengono aggiunti a un singolo file, quindi vale la pena sapere come gestirlo.

require 'yaml' 

yaml = <<EOT 
--- 
alpha: 100.0 
beta: 200.0 
gama: 300.0 
--- 
int: 3 
... 
EOT 

loop do 
    puts YAML.load(yaml) 
    break if !yaml.sub!(/(?<!#)(-{3}.+?(?=-{3})\n?){1}/m,'') 
    break if yaml.empty? 
end 

# >> {"alpha"=>100.0, "beta"=>200.0, "gama"=>300.0} 
# >> {"int"=>3} 
+8

Dovresti semplicemente usare ['load_stream'] (http://ruby-doc.org/stdlib-2.1.0/libdoc/psych/rdoc/Psych.html#method-c-load_stream) piuttosto che farlo da solo (nota la costante 'Psych' è uguale a' YAML' nell'attuale Rubys). – matt

+2

E 'un peccato che la pagina di ruby-doc per [YAML] (http://ruby-doc.org/stdlib-2.1.0/libdoc/yaml/rdoc/YAML.html) non fornisca un collegamento alla documentazione di Psych . Non menziona nemmeno che c'è un'interfaccia pubblica più di "load',' dump' e 'to_yaml'. –

+1

@matt Dovresti pubblicare il tuo commento come risposta, perché in realtà è la risposta corretta alla domanda ed è sepolto sotto una risposta senza voto. –

10

Per accedere a più documenti YAML in un singolo file, utilizzare il metodo load_stream (come già detto da "matt" in un commento ad una delle altre risposte):

YAML.load_stream('test.yml') do |document| 
    puts document 
end