2017-06-15 5 views
0

ruby​​ YAML moduleYAML.load_file(foo)は、fooがYAMLファイルでない場合にnullを返すことを期待したいと思います。しかし例外があります:ファイルがYAMLかどうかを知る

did not find expected alphabetic or numeric character while scanning an alias at line 3 column 3 (Psych::SyntaxError) 
    from /usr/lib/ruby/2.4.0/psych.rb:377:in `parse_stream' 
    from /usr/lib/ruby/2.4.0/psych.rb:325:in `parse' 
    from /usr/lib/ruby/2.4.0/psych.rb:252:in `load' 
    from /usr/lib/ruby/2.4.0/psych.rb:473:in `block in load_file' 
    from /usr/lib/ruby/2.4.0/psych.rb:472:in `open' 
    from /usr/lib/ruby/2.4.0/psych.rb:472:in `load_file' 
    from ./select.rb:27:in `block in selecting' 
    from ./select.rb:26:in `each' 
    from ./select.rb:26:in `selecting' 
    from ./select.rb:47:in `block (2 levels) in <main>' 
    from ./select.rb:46:in `each' 
    from ./select.rb:46:in `block in <main>' 
    from ./select.rb:44:in `each' 
    from ./select.rb:44:in `<main>' 

ファイルが例外なしでYAMLファイルであるかどうかを調べるにはどうしたらいいですか?私の場合、私は、ディレクトリとプロセス値下げファイルに移動します。私は例外をキャッチすると、bucleは要素をプッシュし続けない

mylist = Array.new 
mylist = [] 
for d in (directory - excludinglist) 
begin 
    info = YAML.load_file(d) 
    if info 
    if info.has_key?('output') 
     if info['output'].has_key?(word) 
     mylist.push(d) 
     end 
    end 
    end 
rescue Psych::SyntaxError => error 
    return [] 
end 
end 
return mylist 

私は、キーoutput: wordでリスト値下げファイルに追加して、私はそのリストを返します私のリストに。

+0

はどのようにして' null'なのでを区別します。私。 YAML文書が空であるか、あるいは 'null'(すなわち、 '〜'、 'ヌル'、 'ヌル'と 'ヌル')として表現されるスカラーだけを含んでいますか? – Anthon

答えて

2

短い答え:あなたはできませんが。

YAMLは単なるテキストファイルなので、与えられたテキストファイルがYAMLかどうかを知る唯一の方法は、それを解析することです。パーサーはファイルを解析しようとしますが、有効なYAMLでなければエラーを発生させます。

エラーと例外は、特にIOの世界ではRubyの共通部分です。それらを恐れる理由はありません。あなたは簡単にそれらから救出し、あなたの方法を続けることができます。

begin 
    yaml = YAML.load_file(foo) 
rescue Psych::SyntaxError => e 
    # handle the bad YAML here 
end 

あなたがディレクトリに複数のファイルを処理する必要があるため、次のコードは動作しないことに言及した。

def foo 
    mylist = [] 
    for d in (directory - excludinglist) 
    begin 
     info = YAML.load_file(d) 
     if info 
     if info.has_key?('output') 
      if info['output'].has_key?(word) 
      mylist.push(d) 
      end 
     end 
     end 
    rescue Psych::SyntaxError => error 
     return [] 
    end 
    return mylist 
end 

ここでの唯一の問題エラーが発生したときは、関数から早く戻ってきます。あなたが返されない場合は、forループは継続されますと、あなたの希望する機能を取得します:コンテンツがnull`なので `の有効なコンテンツから有効なYAMLなかったら

def foo 
    mylist = [] 
    for d in (directory - excludinglist) 
    begin 
     info = YAML.load_file(d) 
     if info 
     if info.has_key?('output') 
      if info['output'].has_key?(word) 
      mylist.push(d) 
      end 
     end 
     end 
    rescue Psych::SyntaxError => error 
     # do nothing! 
     # puts "or your could display an error message!" 
    end 
    end 
    return mylist 
end 
+0

これを行うと、ディレクトリ内のすべてのドキュメントを処理できません。私のコードは次のようになり、この ' マイリスト= Array.new \tマイリスト=でDのため[] \t - \t \tが \t \t \t情報を始める(ディレクトリexcludinglist)= YAML.load_file(D) \t \t \t場合情報 \t \t \t \t info.has_keyかの?( '出力') \t \t \t \t \t情報であれば[ '出力']。ヘクタールs_key?(単語) \t \t \t \t \t \t mylistプッシュ(D) \t \t \t \t \t端 \t \t \t \t端 \t \t \t端 \t \tレスキューサイコ::にSyntaxError =>エラー \t \t \tリターン[] \t \t端 \t端 \t戻るmylist' – somenxavier

+0

@ some元の質問を編集して、適切にフォーマットされたコードサンプルを含めることができますか? – eiko

+0

が完了しました。今、私の問題に何らかの解決策を提供できますか?ありがとう – somenxavier

2

Psych::SyntaxErrorは、Cで書かれたソースがPsych::Parser#parseになります.Cで作業しない限り、例外が発生しないようにRubyでメソッドのパッチを書くことはできません。

それでも、あなたは確かにそうよう、例外を救うことができます:

begin 
    foo = YAML.load_file("not_yaml.txt") 
rescue Psych::SyntaxError => error 
    puts "bad yaml" 
end 
関連する問題