我们为什么要避免在其修饰形式中使用救援?

Edi*_*jo' 13 ruby error-handling

我会定义价值.但是这个值可能是哈希键的值.如果此键不存在,我将使用rescue来定义值为nil.例如

foo = bar[:a][:b][:c] rescue nil

但在实践中告诉我糟糕的风格,因为我使用其修饰形式的救援.我将改变逻辑以使用检查三个条件.

foo = bar[:a][:b][:c] if bar.key?(:a) && bar[:a].key?(:b) && bar[:a][:b].key?(:c)

我真的很想知道为什么我们要避免在rails中使用其修改器形式的救援?

mea*_*gar 19

我们为什么要避免在轨道中使用其修改器形式的救援?

首先,因为它隐藏了所有错误,包括你期望的错误和你没有错误的错误,并且一条毯子rescue不能使你的代码的未来读者清楚地知道哪些错误是预期的或意外的.这可能不是一个问题,现在,用一个简单的foo[:a][:b][:c],但在一次有人任意点可能会修改语句来读取foo[:a][:b][some_method]和突然的任何错误,应该泡出来的some_method也被吞噬.

其次,通常有一个更好的不那么全面的解决方案,它更明确地设计为只处理您想要忽略的错误:缺少索引或nil返回值.

在你的情况下,替代方案并不是if && && &&你所建议的大规模.对于哈希,您可以使用其中任何一个dig,它具有所有好处,rescue而不会吞噬可能引发的每种类型的异常:

foo = bar.dig(:a, :b, :c)
Run Code Online (Sandbox Code Playgroud)

类似地,对于链式方法调用,您可以使用try(在Rails中)或安全导航操作符(在Ruby 2.3中):

foo = bar.try(:a).try(:b).try(:c)
# or
foo = bar&.a&.b&.c
Run Code Online (Sandbox Code Playgroud)