2017-06-15 61 views
0

我想指望紅寶石YAML module返回空的YAML.load_file(foo)如果foo不是YAML文件。但我得到異常:知道,如果文件是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文件或並非沒有例外?就我而言,我瀏覽到一個目錄和流程降價文件:我添加到列表降價文件,用鑰匙output: word,我返回列表

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 

當我趕上異常,bucle不繼續推進要素在我的名單上。

+0

你會如何區分'null'如果內容不是從null'的'有效的內容有效YAML。即如果YAML文檔是空的,或者只包含一個表示爲'null'的標量(即'〜','Null','null'和'NULL')? – Anthon

回答

2

答案很簡單:你不能。

因爲YAML只是一個文本文件,要知道一個給定的文本文件是否是YAML與否的唯一方法是分析它。解析器將嘗試解析文件,如果它不是有效的YAML,它會引發錯誤。

錯誤和異常紅寶石的公共部分,尤其是在IO的世界。沒有理由害怕他們。您可以輕鬆地從他們救出,並繼續用自己的方式:

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循環將繼續下去,你會得到你想要的功能:

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

如果我這樣做,那麼我無法處理目錄中的所有文檔。我的代碼看起來像這樣' MYLIST = Array.new \t MYLIST = [] \t在d(目錄 - excludinglist) \t \t開始 \t \t \t信息= YAML.load_file(d) \t \t \t如果信息 \t \t \t \t如果info.has_key?( '輸出') \t \t \t \t \t如果信息[ '輸出']。公頃s_key?(word) \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 nxavier你可以編輯你的原始問題,包括代碼示例,格式正確嗎? – eiko

+0

完成。現在你能爲我的問題提供某種解決方案嗎?感謝 – somenxavier

2

Psych::SyntaxError得到了Psych::Parser#parse的提高,其源代碼是用C編寫的。所以除非你想使用C,否則你不能在Ruby中爲該方法編寫補丁來防止引發異常。

不過,你當然可以救例外,像這樣:

begin 
    foo = YAML.load_file("not_yaml.txt") 
rescue Psych::SyntaxError => error 
    puts "bad yaml" 
end 
相關問題