修饰符形式的三元和救援的短替代

时间:2017-10-17 12:13:13

标签: ruby rescue

加载文件时,我曾经做过一些变体:

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一样简短明了,但没有缺点?

1 个答案:

答案 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;足够好"。