Ruby中的失败与提升:我们真的应该相信风格指南吗?

Ruby提供了两种以编程方式引发exception的可能性: raisefail ,两者都是Kernel方法。 根据文件,它们绝对相同。

出于习惯,我到目前为止只使用了raise 。 现在我找到了一些建议(例如这里 ),使用raise来捕获exception,并且对于不应该处理的严重错误而fail

但它真的有意义吗? 当你编写一个类或模块,并导致内部问题,你发出错误信号时,正在审查代码的编程同事可能会很高兴地理解你的意图,但使用我的代码的人很可能看不到在我的代码中无法知道exception是由raise还是由fail引起的。 因此,我谨慎使用raisefail不会对他的决定产生任何影响,无论她是否应该处理。

有人会在我的论点中看到缺陷吗? 或者是否有其他标准,我可能想要使用fail而不是raise

对于要捕获的exception使用’raise’,对于不打算处理的严重错误使用’failed’

这不是官方风格指南或您提供的链接在此问题上所说的。

这里的意思是仅在rescue区使用raise 。 当你想说某些内容fail时,Aka使用fail ,并在重新抛出exception时使用raise

至于“它有意义”部分 – 它不是最严格遵守的规则之一,但你可以为任何惯例制定相同的论点。 你应该遵循这个顺序:

  1. 您的项目风格指南
  2. 您的公司风格指南
  3. 社区风格指南

理想情况下,三者应该是相同的。


更新 :截至本PR (2015年12月),惯例是始终使用raise

我曾经和Jim Weirich谈过这个问题,因为我的方法由于某种原因明显失败并且raise重新抛出exception时我总是使用fail

这是一篇post,里面有Jim发来的消息(几乎逐字逐句地告诉我他的内容): http : //www.virtuouscode.com/2014/05/21/jim-weirich-on-exceptions/

以下是post中的相关文字,吉姆的一句话:

这是关于exception的基本哲学(以及其他随机思考)。

当您调用方法时,您对该方法将实现的内容有一定的期望。 在forms上,这些期望被称为后置条件。 只要一个方法无法满足其后置条件,它就应抛出exception。

为了有效地使用这一策略,它意味着您必须对“按合同设计”以及前后条件的含义有一点了解。 我认为无论如何都要知道这件事。

这是一些具体的例子。 Rails模型save方法:

 model.save! -- post-condition: The model object is saved. 

如果由于某种原因未保存模型,则必须引发exception,因为不满足后置条件。

 model.save -- post-condition: (the model is saved && result == true) || (the model is not saved && result == false) 

如果save实际上没有保存,那么返回的结果将为false ,但仍然满足后置条件,因此没有exception。

我发现save!很有意思save! 方法具有非常简单的后置条件。

关于拯救例外的问题,我认为应用程序应该具有拯救例外的战略要点。 在大多数情况下,几乎没有必要进行救援/重新投掷。 你想要拯救和重新抛出的唯一一次是当你完成一份工作并且想要撤消某些东西以避免部分完成状态时。 应仔细选择您的战略救援点,以便即使当前操作失败,程序也可以继续其他工作。 事务处理程序应该继续进行下一个事务。 Rails应用程序应该恢复并准备好处理下一个http请求。

大多数exception处理程序应该是通用的。 由于exception表示某种类型的失败,因此处理程序只需要决定在发生故障时该怎么做。 通常不鼓励对非常特定的exception进行详细的恢复操作,除非处理程序非常接近(调用图形)到exception点。

exception不应该用于流量控制,使用throw/catch 。 这保留了真实故障条件的例外情况。

(另外,因为我使用exception来表示失败,所以我几乎总是使用fail关键字而不是Ruby中的raise关键字Fail and raise是同义词,所以没有区别,除非fail更明确地表示方法失败了。只有我使用raise的时候才是我捕捉exception并重新raise它,因为在这里我没有失败,而是明确而有目的地提出exception。这是我遵循的风格问题,但我怀疑很多其他人这样做) 。

在那里你有它,一个相当漫无目的的记忆转储我对exception的想法。

我知道有很多不同意的风格指南 (例如RoboCop使用的风格指南 )。 我不在乎。 吉姆说服了我。