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

use*_*428 35 ruby coding-style exception conventions

Ruby提供了两种以编程方式引发异常的可能性: raise并且fail都是Kernel方法.根据这些文件,它们完全相同.

出于习惯,我raise到目前为止只使用过.现在我找到了几个建议(例如这里),raise用于捕获异常,以及fail用于不应处理的严重错误.

但它真的有意义吗?当你编写一个类或模块,并在内心深处产生问题时fail,你正在查看代码的编程同事可能会很高兴地了解你的意图,但使用我的代码的人很可能不会看到我的代码,无法知道,异常是由a raise还是by 引起的fail.因此,我谨慎使用raisefail不会对他的决定产生任何影响,无论她是否应该处理.

有人会在我的论点中看到瑕疵吗?还是有其他标准,我可能想用fail而不是raise

ndn*_*kov 45

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

这不是官方风格指南或您提供的关于此事的链接.

这里的意思是raise仅在rescue块中使用.Aka fail在您想要说某些内容时失败raise重新抛出异常时使用.

至于"它是否重要"部分 - 它不是最严格遵守的核心规则之一,但你可以为任何惯例制定相同的论点.你应该遵循这个顺序:

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

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


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

  • 谢谢你澄清一下!这让我很清楚(尽管我仍然对这条规则的用处感到有些疑惑,因为我一般可以从代码中轻松看到,我是否重新抛出异常.据我所知,没有任何东西可以获得通过使用不同的命令另外强调这一事实. (2认同)

Kar*_*bur 10

我曾经与Jim Weirich就这件事进行过一次对话,从那以后,fail当我的方法由于某种原因明显失败并raise重新抛出异常时,我一直使用它。

这是一个来自 Jim 的帖子(几乎是逐字逐句地对我说的话):http : //www.virtuouscode.com/2014/05/21/jim-weirich-on-exceptions/

这是帖子中的相关文字,引用自吉姆:

这是我关于异常的基本哲学(和其他随机想法)。

当您调用一个方法时,您对该方法将完成什么有一定的期望。正式地,这些期望被称为后置条件。方法在未能满足其后置条件时应抛出异常。

为了有效地使用这个策略,它意味着你必须对契约设计以及前置和后置条件的含义有一点了解。我认为无论如何知道这是一件好事。

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

model.save!
-- post-condition: The model object is saved.
Run Code Online (Sandbox Code Playgroud)

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

model.save
-- post-condition: (the model is saved && result == true) ||
                   (the model is not saved && result == false)
Run Code Online (Sandbox Code Playgroud)

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

我觉得有趣的是,该save!方法有一个非常简单的后置条件。

关于拯救异常的话题,我认为应用程序应该有拯救异常的策略点。大多数情况下几乎不需要救援/重新投掷。您唯一想要挽救和重新抛出的时间是当您的工作已完成一半并且您想撤消某些内容以避免部分完成状态时。应该仔细选择您的战略救援点,以便即使当前操作失败,程序也可以继续进行其他工作。事务处理程序应该继续进行下一个事务。Rails 应用程序应该恢复并准备好处理下一个 http 请求。

大多数异常处理程序应该是通用的。由于异常表示某种类型的失败,因此处理程序只需要决定在失败的情况下该怎么做。通常不鼓励对非常具体的异常进行详细的恢复操作,除非处理程序非常接近(调用图明智)到异常点。

异常不应该用于流量控制,而是用于流量控制throw/catch。这为真正的故障条件保留了例外。

(顺便说一句,因为我使用异常来表示失败,我几乎总是使用的fail关键字,而不是raise在Ruby的关键字。Failraise是同义词,所以没有什么区别,只是fail更清楚communcates,该方法已经失败。我唯一一次使用raise是当我捕获异常并重新提出它时,因为在这里我没有失败,而是明确而有目的地提出异常。这是我遵循的一个文体问题,但我怀疑很多其他人这样做)。

你有它,我对异常的想法相当杂乱无章的记忆转储。

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