RubyでYAMLファイルを解析するにはどうすればよいですか?


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

しかし、それは機能していないようで、値がnilであるというエラーが表示されます。

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コンソールを起動して、rubyがそのパスも見ることができるかどうかを確認できます。
2010年

ええ、ファイルは存在し、正しい場所にあります。エラーのある投稿を更新しました。
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の素晴らしいところです-何かをシリアル化し、後でそれを読み取ることができるので、なぜその機能を使用しないのですか?
Tin Man、

ああ、私はあなたがYAMLファイルでそれができることを知りませんでした。本当にありがとう!
alvincrespo

1
ああ、それはタブを使っていたからです。タブではなくスペースしか必要としないようで、あらゆる種類のエラーがスローされます。
FilBot3 2014年

3
YAMLライブラリの#loadと#load_fileの違いは何ですか?
Jwan622 2016年

3
YAML.loadYAML文字列をYAML.load_file受け取り、相対ファイルパスを受け取ります。
Narfanator 2016

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



ありがとう@devstuff-回答のリンクを更新しました。
sarfata 2018年

3

以下は、ターミナルから、ymlファイルのコンテンツをテストするために使用する1つのライナーです。

$ 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"}}}}}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.