Как мне разобрать файл YAML в Ruby?

210

Я хотел бы знать, как проанализировать файл YAML со следующим содержанием:

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

В настоящее время я пытаюсь разобрать это так:

@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

Но это не похоже на работу и дает мне ошибку, что значение равно нулю.

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

Если я попробую это, он выдаст всю строку (fo_globallazyload-minholla-min):

if !@custom_asset_packages_yml.nil?
          @custom_asset_packages_yml['javascripts'].each{ |js|
            js['fo_global']
          }
        end
alvincrespo
источник
1
Можете ли вы дать вывод сценария при его запуске? файлы в нужном месте? вы всегда можете запустить консоль Rails и посмотреть, может ли ruby ​​увидеть этот путь.
Лукас
Да, файл существует и находится в нужном месте. Я обновил свой пост с ошибкой.
alvincrespo

Ответы:

449

Может я что-то упустил, но зачем пытаться разобрать файл? Почему бы просто не загрузить YAML и изучить объект (ы), который в результате?

Если ваш образец YAML находится в some.yml, то это:

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

дает мне

{"javascripts"=>[{"fo_global"=>["lazyload-min", "holla-min"]}]}
Майк Вудхаус
источник
9
Я согласен, что замечательно в YAML - мы можем сериализовать что-то, а затем прочитать это позже, так почему бы не использовать эту возможность.
Жестянщик
Ах, я не знал, что вы можете сделать это с файлом YAML. Спасибо!
alvincrespo
1
Да, это потому, что я использовал вкладки. Кажется, что он хочет только пробелы вместо вкладок, а затем выбрасывает всевозможные ошибки.
FilBot3
3
В чем разница между #load и #load_file в библиотеке YAML?
Jwan622
3
YAML.loadпринимает строку YAML, YAML.load_fileпринимает относительный путь к файлу.
Нарфанатор
11

У меня была та же проблема, но я также хотел получить содержимое файла (после фронтальной версии YAML).

Это лучшее решение, которое я нашел:

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

Источник и обсуждение: https://practicingruby.com/articles/tricks-for-working-with-text-and-files

sarfata
источник
1
Ссылка теперь , похоже, practicingruby.com/articles/...
devstuff
Спасибо @devstuff - я обновил ссылку в ответе.
Сарфата
3

Вот один вкладыш, который я использую с терминала, чтобы проверить содержимое файла (ов) 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"}}}}}
зет
источник