Як розібрати файл 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

1
ви можете дати вихід сценарію під час його запуску? файли в потрібному місці? Ви завжди можете запустити консоль Rails і побачити, чи може також побачити рубін.
Лукас

Так, файл існує і знаходиться в потрібному місці. Я оновив свою публікацію з помилкою.
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


1
Здається, посилання зараз практикуєтьсяruby.com
articles/…

Дякую @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"}}}}}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.