Common lisp 公共列表:不同包中的用例处理程序

Common lisp 公共列表:不同包中的用例处理程序,common-lisp,restart,condition-system,Common Lisp,Restart,Condition System,我有以下lisp代码: ;;; hop.lisp (defpackage #:hop (:use #:cl )) (in-package :hop) (export 'hop) (defun hop () (restart-case (error "Hop") (hop () (format t "hop")))) 在这里,我定义了一个总是失败的伪函数,但它提供了一个restart:hop 在另一个包中,在此文件中: ;;; hip.lisp (

我有以下lisp代码:

;;; hop.lisp

(defpackage #:hop
  (:use #:cl ))

(in-package :hop)
(export 'hop)

(defun hop ()
  (restart-case
      (error "Hop")
    (hop ()
      (format t "hop"))))
在这里,我定义了一个总是失败的伪函数,但它提供了一个restart:hop

在另一个包中,在此文件中:

;;; hip.lisp

(defpackage #:hip
  (:use #:cl #:hop))

(in-package :hip)

(defun dhip ()
  (hop:hop))

(defun hip ()
  (handler-case
      (hop:hop)
    (error (e)
      (declare (ignore e))
      (format t "restarts: ~a~%" (compute-restarts))
      (invoke-restart 'hop))))
我定义了从第一个包调用函数(hop)的函数(hip)和(dhip)

当我呼叫(dhip)时,sbcl向我提供一个提示,我可以选择使用我的重新启动跃点重新启动:

Hop
   [Condition of type SIMPLE-ERROR]

Restarts:
 0: [HOP] HOP
 1: [RETRY] Retry SLIME REPL evaluation request.
 2: [*ABORT] Return to SLIME's top level.
 3: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING     {1009868103}>)

Backtrace:
  0: (HOP)
  1: (DHIP)
  2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (DHIP) #<NULL-LEXENV>)
  3: (EVAL (DHIP))
--more--
Hop
[简单错误类型的条件]
重新启动:
0:[跃点]跃点
1:[重试]重试SLIME REPL评估请求。
2:[*中止]返回SLIME的顶层。
3:[中止]中止线程(#)
回溯:
0:(跳)
1:(DHIP)
2:(SB-INT:SIMPLE-EVAL-IN-lexev(DHIP)#
3:(评估(DHIP))
--更多--
这正是我所期望的

但是,当我调用(hip)时,我的重新启动跃点未按(计算重新启动)列出,并且它无法使用它:(

没有活动的重新启动跃点。
[SB-INT类型的条件:简单-控制-错误]
重新启动:
0:[重试]重试SLIME REPL评估请求。
1:[*中止]返回SLIME的顶层。
2:[中止]中止线程(#)
回溯:
0:(SB-INT:FIND-RESTART-OR-CONTROL-ERROR-HOP NIL T)
1:(调用-重新启动跃点)
2:((弗莱特:幽默1:臀部)
3:(臀部)
4:(SB-INT:SIMPLE-EVAL-IN-lexev(HIP)#
5:(评估(髋关节))
你知道该怎么做才能让它起作用吗

谢谢


纪尧尔

这与包裹无关

在HANDLER-CASE中,当处理程序运行时,堆栈已经展开。因此,在函数中建立的重新启动就消失了

改为使用HANDLER-BIND。它在错误上下文中运行处理程序,因此可以重新启动函数

例如:

(defun hip ()
  (handler-bind ((error (lambda (e)
                          (declare (ignore e))
                          (format t "restarts: ~a~%" (compute-restarts))
                          (invoke-restart 'hop))))
      (hop)))
(defun hip ()
  (handler-bind ((error (lambda (e)
                          (declare (ignore e))
                          (format t "restarts: ~a~%" (compute-restarts))
                          (invoke-restart 'hop))))
      (hop)))