Làm cách nào để phân tích tệp YAML trong Ruby?


210

Tôi muốn biết cách phân tích tệp YAML với các nội dung sau:

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

Hiện tại tôi đang cố gắng phân tích nó theo cách này:

@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

Nhưng nó dường như không hoạt động và cho tôi một lỗi rằng giá trị là không.

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

Nếu tôi thử điều này, nó sẽ đưa ra toàn bộ chuỗi (fo_globallazyload-minholla-min):

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

1
bạn có thể đưa ra đầu ra của tập lệnh khi bạn chạy nó không? đúng tập tin? bạn luôn có thể kích hoạt bảng điều khiển Rails và xem liệu ruby ​​có thể nhìn thấy con đường đó không.
Lukas

Vâng, tập tin tồn tại và ở đúng vị trí. Ive cập nhật bài viết của tôi với lỗi.
alvincrespo

Câu trả lời:


449

Có thể tôi đang thiếu một cái gì đó, nhưng tại sao cố gắng phân tích tệp? Tại sao không tải YAML và kiểm tra (các) đối tượng đó?

Nếu YAML mẫu của bạn nằm trong some.yml, thì đây:

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

đưa cho tôi

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

9
Tôi đồng ý, đó là điều tuyệt vời về YAML - chúng ta có thể tuần tự hóa một cái gì đó sau đó đọc lại sau, vậy tại sao không sử dụng khả năng đó.
Tin Man

Ah, tôi không biết rằng bạn có thể làm điều đó với tệp YAML. Cám ơn rất nhiều!
alvincrespo

1
Huh, đó là vì tôi đã sử dụng các tab. Có vẻ như nó chỉ muốn khoảng trắng thay vì các tab, và sau đó ném tất cả các loại lỗi.
FilBot3

3
Sự khác biệt giữa #load và #load_file trong thư viện YAML là gì?
Jwan622

3
YAML.loadlấy một chuỗi YAML, YAML.load_filelấy một đường dẫn tệp tương đối.
Narfanator

11

Tôi đã có cùng một vấn đề nhưng cũng muốn có được nội dung của tập tin (sau vấn đề trước YAML).

Đây là giải pháp tốt nhất tôi đã tìm thấy:

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

Nguồn và thảo luận: https://practectingruby.com/articles/tricks-for-usiness-with-text-and-files


1
Liên kết bây giờ có vẻ như đang thực
hànhruby.com /articles / từ

Cảm ơn @dev ware - Tôi đã cập nhật liên kết trong câu trả lời.
sarfata

3

Đây là một lớp lót tôi sử dụng, từ thiết bị đầu cuối, để kiểm tra nội dung của tệp 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"}}}}}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.