为什么ZeroDivide可以恢复?

时间:2014-12-28 18:11:11

标签: smalltalk

在Pharo(和其他方言)中,ZeroDivide例外可以恢复。为什么?。例如,如果您评估1 / 0然后继续,则答案是ZeroDivide错误。为什么是这样? ZeroDivide不应该不可恢复吗?

修改: 让我们更深入地回顾这个问题。

这里的问题是,如果异常发生,我们得到的是ZeroDivide异常。因此,我可以考虑使这个异常可恢复的唯一原因是启用以下内容:

[a / b] on: ZeroDivide do: [:ex | ex resume: self anythingButTheQuotient],

正确?

但这也可以写成

[a / b] on: ZeroDevide do: [self anythingButTheQuotient]

不要求例外情况可以恢复。

如果存在“有趣的”#defaultAction,则可恢复的异常是有意义的。但ZeroDivide似乎并非如此。

有人可能会说,在许多情况下,人们会有这样的代码:

b = 0 ifTrue: [^0] ifFalse: [^a / b]

那么为什么不使用0作为#defaultAction?这将使上述代码更简单(在这些情况下),并且只需要(可以说)少数必须表现不同的特殊处理程序。但是,这将是一个非常糟糕的决定,因为默认行为会隐藏错误,正如我们所知,它们表现出最差的错误。

1 个答案:

答案 0 :(得分:3)

是的,乍看起来令人惊讶,但ANSI标准说:

  

零分割例外可以恢复,因此该协议中的任何消息都是如此   发出此类异常的信号最终可能会返回给发件人。

你给出的例子是微不足道的,但是当安装处理程序上面的一些方法时,恢复发出信号的异常就不那么容易了。

[self doSomethingComplex]
    on: ZeroDivide
    do:
        [:exception |
        "Handle zero divide as inf/nan as if performed in floating point arithmetic"
        exception resume: exception dividend asFloat / 0.0] 

在Squeak或Pharo中,请参阅类signalContext中对Exception实例变量的引用。您将看到恢复是将控制权返回给信号员的唯一选择。