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
Alvincrespo
quelle
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"]}]}
Mike Woodhouse
quelle
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

sarfata
quelle
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"}}}}}
zee
quelle