lisp - 在常见的 lisp 中,你如何在抛出错误但未被捕获的地方重新启动?

标签 lisp common-lisp restart condition-system

这个问题其实是我对重启的理解不够。

cl-json 的编码器中有一个我想使用的诱人宏

with-substitute-printed-representation-restart

但是,唉,我不太明白这是怎么回事。

这个

(cl-json::encode-json-plist (list :boo "boo" :foo "foo"))

返回

{"boo":"boo","foo":"foo"}

这个

(cl-json::encode-json-plist (list :boo "boo" :foo  (lambda (a b) (+ a b))))

发出不可编码值错误信号

我想从 cl-json 找到函数并让它返回的那一点重新开始 当它遇到我在列表中添加的 lambda 时,我会选择一些东西。

(defun my-func ()
 (handler-bind ((cl-json::UNENCODABLE-VALUE-ERROR 
                #'(lambda (e) (invoke-restart 'return-default))))
   (myencode (list :boo "boo" :foo (lambda (a b) (+ a b))))
 )
)

(defun myencode (alist)
 (restart-case
  (cl-json::encode-json-plist-to-string alist)
  (return-default () :report "Just return a default could not do this string" "barf")
 )
)

返回“呕吐”

我要它回来

{"boo":"boo","foo":"barf"}

我该如何使用那个宏来做这个? 换句话说,我希望在抛出错误的地方而不是在捕获错误的地方重新启动。我可以这样做吗?

最佳答案

我不明白文档是否有误,或者我是否在错误地阅读代码,但只要无法对对象进行编码,就应该已经可以重新启动。如果您如下重新定义了 cl-jsonencode-json 默认方法,那么您需要重新启动。

(defmethod encode-json (anything &optional (stream *json-output*))
  "If OBJECT is not handled by any specialized encoder signal an error
which the user can correct by choosing to encode the string which is
the printed representation of the OBJECT."
  (with-substitute-printed-representation-restart (anything stream)
    (unencodable-value-error anything 'encode-json)))

顺便说一句,您可以重新定义以便重新启动接受一个参数,即要打印的字符串:

(defmethod encode-json (anything &optional (stream *json-output*))
  "If OBJECT is not handled by any specialized encoder signal an error
which the user can correct by choosing to encode the string which is
the printed representation of the OBJECT."
  (with-substitute-printed-representation-restart (anything stream)
    (restart-case (unencodable-value-error anything 'encode-json)
      (use-value (v)
        :report "Use a different encoding"
        (check-type v string)
        (write v :stream stream :escape t)))))

例如:

CL-USER> (handler-bind
                ((json:unencodable-value-error
                  (lambda (err)
                    (declare (ignore err))
                    (invoke-restart 'use-value "UNKNOWN"))))
              (json:encode-json
               `(((foo . ,#'print) (bar . "baz")))))
[{"foo":"UNKNOWN","bar":"baz"}]

你可能想直接问图书馆的作者

关于lisp - 在常见的 lisp 中,你如何在抛出错误但未被捕获的地方重新启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64175849/

相关文章:

vim - 使用 SLIMV 编写 Lisp 代码,如何在不禁用 paredit.vim 的情况下插入单个“?

python - 如何在 “stack overflow error”之后自动重新运行python代码

ssl - 单边SSL带CL+SSL包

clojure - 我怎样才能避免使用连续传递风格的堆栈?

stream - SICP 无限流(第 3.5.2 章)

Lisp - 函数的函数调用接收的参数太少?

lisp - Scheme 中的二叉搜索树,如果 BST 中存在值,则尝试使用 Dr. Racket 简单地返回 true 或 false。错误

shell - 如何在 common lisp 中导航文件系统

java - 如何重绘 - 在处理中重新启动循环

c++ - Windows/C++中是否有 'restart'函数