gpt4 book ai didi

common-lisp - 非宏的 HANDLER-CASE 替代方案

转载 作者:行者123 更新时间:2023-12-01 11:20:43 25 4
gpt4 key购买 nike

因此请考虑以下代码:

(define-condition some-condition (error) nil)

(defmethod print-object ((obj some-condition) stream)
(format stream "HELLO THERE"))

(defmacro error-report-test-aux (fn-to-cause-error error-type-to-catch fn-to-handle-error expected-message)
`(let ((result-message
(handler-case (funcall ,fn-to-cause-error)
(,error-type-to-catch (e) (funcall ,fn-to-handle-error e)))))
(assert (string= result-message
,expected-message))
t))

我可以这样使用它:

(error-report-test-aux (lambda () (error 'some-condition)) 
some-condition
#'princ-to-string
"HELLO THERE")

但我想让 error-report-test-aux 成为一个函数而不是宏,这样我就可以在变量中向它传递一种条件。

简单地写 defun 而不是 defmacro 并删除反引号和逗号是行不通的,因为 handler-case 是宏,它不会' t 评估 error-type-to-catch

我的问题是:是否有类似handler-case 的东西可以评估它的参数(特别是条件类型参数)?

最佳答案

是也不是:-)

您的确切问题

没有标准函数可以做你想做的事,因为捕获错误需要建立绑定(bind),而且人们通常希望绑定(bind)常量符号(如 let/let* ),因为它更容易优化。

可能考虑使用 handler-bind 创建“通用”处理程序然后拒绝处理“无趣”的条件(正如@jkiiski 在评论中所建议的那样),但我不确定这是否符合您的具体要求(未经测试!):

(defun error-report-test-aux (fn-to-cause-error error-type-to-catch expected-message)
(catch 'trap
(handler-bind ((error
(lambda (condition)
(when (typep condition error-type-to-catch)
(throw 'trap (string= (princ-to-string condition)
expected-message))))))
(funcall fn-to-cause-error))))

,特定于实现

IF 您的实现实现了 handler-case/handler-bind通过绑定(bind)内部全局变量,您可以使用 progv自己绑定(bind)它,从而将您的 error-report-test-aux 作为函数实现。

这可能不是最好的主意(您的代码会绑定(bind)到特定的实现)。

,有点

您可以利用 some-condition 命名 CLOS 类并使用通用函数代替宏这一事实。

关于common-lisp - 非宏的 HANDLER-CASE 替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43983522/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com