Comment analyser un fichier YAML dans Ruby?

210

Je voudrais savoir comment analyser un fichier YAML avec le contenu suivant:

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

Actuellement, j'essaie de l'analyser de cette façon:

@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

Mais cela ne semble pas fonctionner et me donne une erreur que la valeur est nulle.

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

Si j'essaye, cela met la chaîne entière (fo_globallazyload-minholla-min):

if !@custom_asset_packages_yml.nil?
          @custom_asset_packages_yml['javascripts'].each{ |js|
            js['fo_global']
          }
        end
alvincrespo
la source
1
pouvez-vous donner la sortie du script lorsque vous l'exécutez? fichiers au bon endroit? vous pouvez toujours lancer une console Rails et voir si ruby ​​peut également voir ce chemin.
Lukas
Oui, le fichier existe et est au bon endroit. J'ai mis à jour mon message avec l'erreur.
alvincrespo

Réponses:

449

Il me manque peut-être quelque chose, mais pourquoi essayer d'analyser le fichier? Pourquoi ne pas simplement charger le YAML et examiner les objets qui en résultent?

Si votre exemple YAML est dedans some.yml, alors ceci:

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

Donne moi

{"javascripts"=>[{"fo_global"=>["lazyload-min", "holla-min"]}]}
Mike Woodhouse
la source
9
Je suis d'accord, c'est le merveilleux de YAML - nous pouvons sérialiser quelque chose puis le relire plus tard, alors pourquoi ne pas utiliser cette capacité.
The Tin Man
Ah, je ne savais pas que vous pouviez le faire avec un fichier YAML. Merci beaucoup!
alvincrespo
1
Huh, c'était parce que j'utilisais des onglets. Il semble qu'il ne veuille que des espaces au lieu d'onglets, puis lance toutes sortes d'erreurs.
FilBot3
3
Quelle est la différence entre #load et #load_file dans la bibliothèque YAML?
Jwan622
3
YAML.loadprend une chaîne YAML, YAML.load_fileprend un chemin de fichier relatif.
Narfanator
11

J'ai eu le même problème, mais je voulais également obtenir le contenu du fichier (après la première page de YAML).

C'est la meilleure solution que j'ai trouvée:

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

Source et discussion: https://practicingruby.com/articles/tricks-for-working-with-text-and-files

Sarfata
la source
1
Le lien semble maintenant être pratiquantruby.com/articles/…
devstuff
Merci @devstuff - J'ai mis à jour le lien dans la réponse.
sarfata
3

Voici le liner que j'utilise, depuis le terminal, pour tester le contenu des fichiers 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"}}}}}
zee
la source