Como analiso um arquivo YAML no Ruby?

210

Gostaria de saber como analisar um arquivo YAML com o seguinte conteúdo:

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

Atualmente, estou tentando analisá-lo desta maneira:

@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

Mas isso não parece funcionar e me dá um erro que o valor é nulo.

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 eu tentar isso, ele coloca a string inteira (fo_globallazyload-minholla-min):

if !@custom_asset_packages_yml.nil?
          @custom_asset_packages_yml['javascripts'].each{ |js|
            js['fo_global']
          }
        end
alvincrespo
fonte
1
você pode dar a saída do script quando você o executa? arquivos no lugar certo? você sempre pode ativar um console do Rails e ver se o ruby ​​também pode ver esse caminho.
Lukas
Sim, o arquivo existe e está no local certo. Atualizei minha postagem com o erro.
Alvincrespo 6/10/10

Respostas:

449

Talvez esteja faltando alguma coisa, mas por que tentar analisar o arquivo? Por que não carregar o YAML e examinar o (s) objeto (s) resultante (s)?

Se sua amostra de YAML estiver some.yml, então:

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

me dá

{"javascripts"=>[{"fo_global"=>["lazyload-min", "holla-min"]}]}
Mike Woodhouse
fonte
9
Eu concordo, isso é maravilhoso na YAML - podemos serializar algo e depois lê-lo novamente mais tarde, então por que não usar esse recurso.
the Tin Man
Ah, eu não sabia que você poderia fazer isso com um arquivo YAML. Muito obrigado!
alvincrespo
1
Foi porque eu estava usando abas. Parece que ele só quer espaços em vez de guias e, em seguida, lança todos os tipos de erros.
FilBot3
3
Qual é a diferença entre #load e #load_file na biblioteca YAML?
Jwan622
3
YAML.loadusa uma string YAML, YAML.load_fileusa um caminho de arquivo relativo.
Narfanator
11

Eu tive o mesmo problema, mas também queria obter o conteúdo do arquivo (após o front-matter do YAML).

Esta é a melhor solução que encontrei:

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 discussão: https://practicingruby.com/articles/tricks-for-working-with-text-and-files

sarfata
fonte
1
O link agora parece estar praticando
Ruby.com/articles/…
Obrigado @ devstuff - Eu atualizei o link na resposta.
sarfata
3

Aqui está o liner que eu uso, no terminal, para testar o conteúdo dos arquivos 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
fonte