放松保护 - 它是如何工作的

时间:2012-10-21 16:20:49

标签: common-lisp sbcl

我正在使用sbcl 1.0.57.0并希望通过--eval启动一个程序,它应该生成一些输出,但是如果有未被捕获的错误,它将退出。

我认为最简单的方法是使用unwind-protect:

(unwind-protect (error 'simple-error) 
  (progn (FORMAT t "IAMREACHED~%") (sb-ext:exit)))

由于(sb-ext:exit)应该执行,因此存在未被捕获的错误。

但事实并非如此!

* (unwind-protect (error 'simple-error) 

       (progn (FORMAT t "IAMREACHED~%") (sb-ext:exit)))

    debugger invoked on a SIMPLE-ERROR in thread
    #<THREAD "main thread" RUNNING {1002979193}>:
    (A SIMPLE-ERROR was caught when trying to print *DEBUG-CONDITION* when entering
    the debugger. Printing was aborted and the SIMPLE-ERROR was stored in
    SB-DEBUG::*NESTED-DEBUG-CONDITION*.)

    Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

    restarts (invokable by number or by possibly-abbreviated name):
      0: [ABORT] Exit debugger, returning to top level.

    (#:EVAL-THUNK)
    0] 0
    IAMREACHED

我对放松保护的运作有何误解?

3 个答案:

答案 0 :(得分:8)

UNWIND-PROTECT是Java或Python中finally子句的类似物,因此它不是一个catch-all子句,它将拦截任何未处理的条件。为此,您需要一个HANDLER-CASE,其中包含CONDITION类型的处理程序子句。

UNWIND-PROTECT实际上适用于您的情况。唯一的“意外”行为是在UNWIND-PROTECT的主体执行之前调用调试器。这样做的原因不是丢失当前上下文并且能够重新开始执行。它(可能)是通过HANDLER-BIND实现的。您可以在PCL章节"Conditions and Restarts"中了解更多相关信息。

答案 1 :(得分:2)

也许您想要禁用调试器,请参阅SBCL Toplevel Options

答案 2 :(得分:0)

您可以使用(ignore-errors)来静默省略错误。 或者你可以提前调用sb-ext:disable-debugger,只在没有调试器启动的情况下看到错误消息。