2017-10-17 33 views
1

當加載文件,我以前做的一些變種:短替代三元和救援修飾形式

first_file = "#{__dir__}/first_file.txt" 
first_data = File.exist?(first_file) ? File.readlines(first_file) : [] 

second_file = "#{__dir__}/second_file.yaml" 
second_data = File.exist?(second_file) ? YAML.load_file(second_file) : {} 

總是坐着有點不對勁了我。需要檢查,看看文件是否存在,需要在那裏,但我真正關心的是後來的事情。

最後,我發現在線rescue,並開始做這樣的:

first_file = "#{__dir__}/first_file.txt" 
first_data = File.readlines(firs_file) rescue [] 

second_file = "#{__dir__}/second_file.yaml" 
second_data = YAML.load_file(second_file) rescue {} 

這對我來說是這樣清晰的 - 嘗試這個東西你真的想,如果你不能做到這一點其他的事情,正是你想要的回退。它比三元組更短,更清晰。

但是,無論在哪裏,我都會重複一遍avoid rescue in modifier form。我明白這是爲什麼:它可以隱藏我們沒有預測到的錯誤。

如果我可以定義Errno::ENOENT作爲從內聯形式到rescue的錯誤,我會的。但據我所知,內聯rescue無法指定要從中解救出什麼錯誤。

那麼選擇是什麼?我可以做什麼,如同內嵌rescue一樣簡短明瞭,但沒有缺點?

+2

回到你的老路。 – sawa

+0

我同意塞爾吉奧,聰明的一個內襯很多時候都不那麼可讀。只需創建一些輔助方法。 –

+0

我想我很清楚爲什麼我不想回到舊的方式。如果唯一的論點是「回到舊的方式」,不妨堅持新的。 – user137369

回答

2

如果我是真的擔心這些行的可讀性,我會創建一些輔助方法。

def read_with_fallback(filename, fallback) 
    File.exist?(filename) ? yield(File.open(filename)) : fallback 
end 

def safe_read_lines(filename) 
    read_with_fallback(first_file, []) {|file| file.readlines } 
end 

def safe_read_yaml(filename) 
    read_with_fallback(second_file, {}) {|file| YAML.parse(file.read) } 
end 

first_file = "#{__dir__}/first_file.txt" 
first_data = safe_read_lines(first_file) 

second_file = "#{__dir__}/second_file.yaml" 
second_data = safe_read_yaml(second_file) 

但是,如果我有一個或兩個那些並沒有重複他們在所有其他方法,那麼我不會理會。你的第一個表格「夠好」。

+1

「我會創建一些輔助方法」 - 我的眼睛正在流血:)你是否真的認爲,這個代碼的未來讀者的神祕'safe_read_lines'(誰至少在紅寶石級別完成1級)比'File .readlines(firs_file)rescue []'? – mudasobwa

+0

@mudasobwa:命名可以改善,毫無疑問。但是,是的,我確實相信這個「​​在閱讀這個yaml文件時盡力而爲」的概念在給出一個名字時讀起來會更好。更高層次的抽象。 'YAML.load_file(second_file)rescue {}' - 這是用至少4位「信息」表示的,實際上它只是一個,「讀取yaml文件」。爲什麼要編譯代碼。試圖在可以避免時推斷代碼的意義?另外,請閱讀最後一部分:) –

+0

@mudasobwa:關於該方法也沒有什麼「神祕」的。它的定義是一鍵(帶有動力編輯器的人):) –