【问题标题】:In common lisp how do you restart where the error was thrown not caught?在常见的 lisp 中,您如何在未捕获错误的地方重新启动?
【发布时间】:2020-10-02 17:25:57
【问题描述】:

这个问题真的是我对重启缺乏了解。

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))))

表示 UNENCODABLE-VALUE-ERROR

我想从 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")
 )
)

返回“barf”

我希望它返回

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

如何使用该宏来执行此操作? 换句话说,我希望在引发错误的地方而不是在捕获错误的地方重新启动。我可以这样做吗?

【问题讨论】:

    标签: lisp common-lisp restart condition-system


    【解决方案1】:

    我不明白文档是错误的还是我阅读代码的方式很糟糕,但是当无法对对象进行编码时,应该已经可以重新启动。如果您为encode-json 重新定义cl-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"}]
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-30
      • 2023-03-13
      相关资源
      最近更新 更多