Wie analysiere ich eine YAML-Datei in Ruby?


210

Ich möchte wissen, wie man eine YAML-Datei mit folgendem Inhalt analysiert:

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

Derzeit versuche ich es folgendermaßen zu analysieren:

@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

Aber es scheint nicht zu funktionieren und gibt mir den Fehler, dass der Wert Null ist.

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

Wenn ich das versuche, wird der gesamte String gelöscht (fo_globallazyload-minholla-min):

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

1
Können Sie die Ausgabe des Skripts angeben, wenn Sie es ausführen? Dateien am richtigen Ort? Sie können jederzeit eine Rails-Konsole starten und prüfen, ob Ruby diesen Pfad auch sehen kann.
Lukas

Ja, die Datei existiert und befindet sich am richtigen Ort. Ich habe meinen Beitrag mit dem Fehler aktualisiert.
Alvincrespo

Antworten:


449

Vielleicht fehlt mir etwas, aber warum sollte ich versuchen, die Datei zu analysieren? Warum nicht einfach die YAML laden und die resultierenden Objekte untersuchen?

Wenn sich Ihre Beispiel-YAML in befindet some.yml, gilt Folgendes :

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

gibt mir

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

9
Ich stimme zu, das ist das Wunderbare an YAML - wir können etwas serialisieren und später wieder einlesen. Warum also nicht diese Funktion nutzen?
der Blechmann

Ah, ich wusste nicht, dass Sie das mit einer YAML-Datei machen können. Vielen Dank!
Alvincrespo

1
Huh, es war, weil ich Tabs benutzte. Es scheint, dass es nur Leerzeichen anstelle von Tabulatoren möchte und dann alle möglichen Fehler auslöst.
FilBot3

3
Was ist der Unterschied zwischen #load und #load_file in der YAML-Bibliothek?
Jwan622

3
YAML.loadNimmt eine YAML-Zeichenfolge und YAML.load_fileeinen relativen Dateipfad.
Narfanator

11

Ich hatte das gleiche Problem, wollte aber auch den Inhalt der Datei erhalten (nach der YAML-Front-Angelegenheit).

Dies ist die beste Lösung, die ich gefunden habe:

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

Quelle und Diskussion: https://practicingruby.com/articles/tricks-for-working-with-text-and-files


1
Link scheint jetzt zu sein practicingruby.com/articles/...
devstuff

Danke @devstuff - Ich habe den Link in der Antwort aktualisiert.
Sarfata

3

Hier ist der eine Liner, den ich vom Terminal aus verwende, um den Inhalt von yml-Dateien zu testen:

$ 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"}}}}}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.