1

在S. Keene的 COMMON LISP 中的面向对象编程一书中,她介绍了通过为某些类describe提供:after方法来专门化泛型函数的行为,但这会导致 SBCL 和 Clozure 中的错误:

COMMON-LISP:DESCRIBE already names an ordinary function or a
macro. [Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]

当我尝试describe为我的班级修改行为时会发生这种情况:

(defclass klasse ()
  ())

(defmethod describe :after ((obj klasse))
  (print "Klasse!"))

由于这本书是 1989 年的,这些锁定策略是在本书发行后发生的,还是我错过了其他东西?

4

1 回答 1

2

据我所知,这本书描述了 ANSI 标准化时代之前的语言(标准化发生在 1994 年)。在 ansi cldescribe中确实是普通函数,而有一个通用的,名为describe-object

CLHS 在这个问题上说如下:

描述对象的实际行为是由 describe-object 实现的。describe 作为一个接口存在,主要用于管理参数默认设置(包括将参数 t 和 nil 转换为流对象)并禁止来自 describe-object 的任何返回值。

所以,你需要做的是指定

(defmethod describe-object :after ((obj klasse) stm) 
    (print "Klasse!" stm)) 

并用描述调用它:

CL-USER> (describe (make-instance 'klasse))
;;=> #<KLASSE {1001C3C1F3}>
;;     [standard-object]
;;   No slots.

;;   "Klasse!" 
;;   ; No values
于 2020-04-13T10:49:41.450 回答