当我尝试在 SBCL 中以导致名称冲突的方式重新定义包时,重新启动时出现 NAME-CONFLICT
错误
0: [KEEP-OLD] Keep symbols already accessible FOO (shadowing others).
1: [TAKE-NEW] Make newly exposed symbols accessible in FOO, uninterning old ones.
2: [RESOLVE-CONFLICT] Resolve conflict.
3: [RETRY] Retry SLIME REPL evaluation request.
4: [*ABORT] Return to SLIME's top level.
5: [ABORT] Abort thread (#<THREAD "new-repl-thread" RUNNING {10060E47B3}>)
我想写一些东西来自动调用TAKE-NEW
重新启动,这样我就可以做类似的事情
(force (defpackage :foo (:use :cl :bar :baz :mumble)))
此结果应与调用 defpackage
相同,然后手动调用 TAKE-NEW
重新启动。问题是,
CL-USER> (handler-case
(defpackage :foo (:use :cl :bar :baz :mumble))
(error (e) (compute-restarts e)))
(#<RESTART SWANK::RETRY {1006DC40F3}> #<RESTART ABORT {10068007E3}>
#<RESTART ABORT {10060C7F93}>)
CL-USER>
我似乎无法访问该特定的重新启动。当我尝试调用它时确认:
CL-USER> (handler-case
(defpackage :foo (:use :cl :bar :baz :mumble))
(name-conflict (e) (invoke-restart 'take-new)))
No restart TAKE-NEW is active.
[Condition of type SB-INT:SIMPLE-CONTROL-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort thread (#<THREAD "new-repl-thread" RUNNING {10060E47B3}>)
有什么想法吗?
最佳答案
handler-case
在将控制权转移给处理程序之前退出重新启动的范围;您需要处理程序绑定(bind)
。构造之间的另外两个区别是 handler-bind 具有不同的语法(如下所示),并且 handler-bind 不传输控制权 - 也就是说,一个 handler-bind 处理程序,用于返回显式转移控制所需的值,例如使用return-from
或invoke-restart
。
类似以下内容应该有效:
(handler-bind ((sb-ext:name-conflict
(lambda (c)
(when (find-restart 'sb-impl::take-new c)
(invoke-restart 'sb-impl::take-new)))))
(defpackage :foo (:use :mumble)))
关于error-handling - 在 SBCL 中使用 [Take New] 重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25773251/