Jak parsować plik YAML w Ruby?


210

Chciałbym wiedzieć, jak analizować plik YAML z następującą zawartością:

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

Obecnie próbuję to przeanalizować w ten sposób:

@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

Ale to nie wydaje się działać i daje mi błąd, że wartość wynosi 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

Jeśli spróbuję tego, wypisze cały ciąg (fo_globallazyload-minholla-min):

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

1
czy możesz podać wynik skryptu po uruchomieniu? pliki we właściwym miejscu? zawsze możesz odpalić konsolę Rails i sprawdzić, czy Ruby również widzi tę ścieżkę.
Lukas

Tak, plik istnieje i znajduje się we właściwej lokalizacji. Zaktualizowałem swój post z błędem.
alvincrespo

Odpowiedzi:


449

Może czegoś mi brakuje, ale po co próbować parsować plik? Dlaczego nie załadować YAML i zbadać obiekty, które wynikają?

Jeśli masz próbkę YAML some.yml, to:

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

daje mi

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

9
Zgadzam się, że to wspaniałe w YAML - możemy serializować coś, a następnie przeczytać to później, więc dlaczego nie skorzystać z tej możliwości.
Tin Man

Ach, nie wiedziałem, że możesz to zrobić za pomocą pliku YAML. Dzięki wielkie!
alvincrespo

1
Huh, to dlatego, że używałem kart. Wydaje się, że chce tylko spacji zamiast tabulatorów, a następnie generuje różnego rodzaju błędy.
FilBot3

3
Jaka jest różnica między plikiem #load i #load_file w bibliotece YAML?
Jwan622,

3
YAML.loadpobiera ciąg YAML, YAML.load_filepobiera względną ścieżkę pliku.
Narfanator,

11

Miałem ten sam problem, ale chciałem też uzyskać zawartość pliku (po froncie YAML).

To najlepsze rozwiązanie, jakie znalazłem:

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

Źródło i dyskusja: https://practicingruby.com/articles/tricks-for-working-with-text-and-files


1
Link wydaje się być practicingruby.com/articles/...
devstuff

Dzięki @devstuff - zaktualizowałem link w odpowiedzi.
sarfata

3

Oto jeden linijka, której używam z terminala do testowania zawartości plików 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"}}}}}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.