Come posso analizzare un file YAML in Ruby?


210

Vorrei sapere come analizzare un file YAML con i seguenti contenuti:

--- 
javascripts: 
- fo_global:
  - lazyload-min
  - holla-min

Attualmente sto cercando di analizzarlo in questo modo:

@custom_asset_packages_yml = (File.exists?("#{RAILS_ROOT}/config/asset_packages.yml") ? YAML.load_file("#{RAILS_ROOT}/config/asset_packages.yml") : nil)
    if !@custom_asset_packages_yml.nil?
      @custom_asset_packages_yml['javascripts'].each{ |js|
        js['fo_global'].each{ |script|
         script
        }
      }
    end

Ma non sembra funzionare e mi dà un errore che il valore è zero.

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each

Se provo questo, mette fuori l'intera stringa (fo_globallazyload-minholla-min):

if !@custom_asset_packages_yml.nil?
          @custom_asset_packages_yml['javascripts'].each{ |js|
            js['fo_global']
          }
        end

1
puoi dare l'output dello script quando lo esegui? file nel posto giusto? puoi sempre avviare una console Rails e vedere se anche ruby ​​può vedere quel percorso.
Lukas,

Sì, il file esiste ed è nella posizione giusta. Ho aggiornato il mio post con l'errore.
alvincrespo,

Risposte:


449

Forse mi manca qualcosa, ma perché provare ad analizzare il file? Perché non caricare semplicemente YAML ed esaminare gli oggetti che risultano?

Se il tuo esempio YAML è presente some.yml, allora questo:

require 'yaml'
thing = YAML.load_file('some.yml')
puts thing.inspect

mi da

{"javascripts"=>[{"fo_global"=>["lazyload-min", "holla-min"]}]}

9
Sono d'accordo, questo è il bello di YAML: possiamo serializzare qualcosa e rileggerlo più tardi, quindi perché non usare questa funzionalità.
Tin Man,

Ah, non sapevo che potevi farlo con un file YAML. Grazie mille!
alvincrespo,

1
Eh, è stato perché stavo usando le schede. Sembra che voglia solo spazi anziché tabulazioni, quindi genera tutti i tipi di errori.
FilBot3,

3
Qual è la differenza tra #load e #load_file nella libreria YAML?
Jwan622,

3
YAML.loadaccetta una stringa YAML, YAML.load_fileaccetta un percorso file relativo.
Narfanator,

11

Ho avuto lo stesso problema, ma volevo anche ottenere il contenuto del file (dopo la prima questione YAML).

Questa è la migliore soluzione che ho trovato:

if (md = contents.match(/^(?<metadata>---\s*\n.*?\n?)^(---\s*$\n?)/m))
  self.contents = md.post_match
  self.metadata = YAML.load(md[:metadata])
end

Fonte e discussione: https://practicingruby.com/articles/tricks-for-working-with-text-and-files


1
Il link ora sembra essere practicingruby.com/articles/…
devstuff

Grazie @devstuff - Ho aggiornato il link nella risposta.
sarfata,

3

Ecco quello che uso, dal terminale, per testare il contenuto dei file yml:

$ ruby  -r yaml -r pp  -e 'pp YAML.load_file("/Users/za/project/application.yml")'
{"logging"=>
  {"path"=>"/var/logs/",
   "file"=>"TacoCloud.log",
   "level"=>
    {"root"=>"WARN", "org"=>{"springframework"=>{"security"=>"DEBUG"}}}}}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.