加载文件时,我曾经做过一些变体:
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
一样简短明了,但没有缺点?
答案 0 :(得分: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)
但如果我只有其中的一两个并且不必在其他方法中重复它们,那么我就不会烦恼了。你的第一个表格是#34;足够好"。