如何在定义条件对象中获取和传递哈希表?

时间:2019-01-23 08:53:34

标签: common-lisp

我正在尝试打印我创建的定义条件的错误消息:

Field:=3

我想做的是下面的一个断言库,在该库中我可以在发生故障时引发错误,以便测试运行程序捕获它并使用作为哈希表的对象来表明它在哪里错误。我不知道如何将此has-table传递给错误,我可以传递:message吗?我想这是不推荐的。以及以后如何赎回它甚至是:message?

尝试捕获错误的示例:

(defun is-t? (actual)
  (assertion (create-result (equal t actual) actual t 'equal)))

(defun create-result (result actual expected operator)
  (let ((assert-result (make-hash-table)) (message))
    (setf message (concatenate 'string (string actual) " " (string operator) " " (string expected)))
    (setf (gethash 'result assert-result) result)
    (setf (gethash 'actual assert-result) actual)
    (setf (gethash 'expected assert-result) expected)
    (setf (gethash 'message assert-result) message)
    assert-result))

(defun assertion (assert-result)
  (unless (gethash 'result assert-result)
    (error 'assertion-error :message (gethash 'message assert-result))))

(define-condition assertion-error (error)
  ((message :initarg :message :reader error-message)))

如何访问:message以及如何通过哈希表进行访问?

2 个答案:

答案 0 :(得分:4)

  

我如何访问:message?

您可以使用其:reader:accessor对其进行访问。在这里,您可以执行(error-message c)

访问器既是“获取器”又是“设置器”。我邀请您在此处阅读有关对象系统的更多信息:{https://lispcookbook.github.io/cl-cookbook/clos.html#getters-and-setters-accessor-reader-writer

  

我如何传递哈希表来访问它?

条件不是严格的类,但实际上非常相似。我们可以使用相应的读取器,写入器或访问器来定义许多插槽,我们不限于message插槽。因此,正如Svante所说,与其存储哈希表,不如将其存储在其他插槽中。或创建一个“结果”插槽,您可以向该插槽提供哈希表。

(define-condition assertion-error (error)
  ((message :initarg :message :reader error-message)
   (expected :initarg :expected :accessor assertion-expected)
   (actual …)
   (result …))
  (:report …))

要设置“预期”:(setf (assertion-expected c) <value>)

:report是调试器中显示的内容:https://lispcookbook.github.io/cl-cookbook/error_handling.html#defining-and-making-conditions

答案 1 :(得分:3)

要更改输出,您需要覆盖报告功能:

(define-condition assertion-error (error)
  ((expected :initarg :expected :reader assertion-expected)
   (actual :initarg :actual :reader assertion-actual))
  (:report (lambda (condition stream)
             (format stream
                     "Assertion failed.  Expected ~s but got ~s instead."
                     (assertion-expected condition)
                     (assertion-actual condition)))))

如您所见,您不需要额外的哈希表。条件对象已经提供了命名槽等。这也是您进行格式化的地方,因此您无需在投掷点格式化消息。