我应该传递什么文档类型来获取 class 的文档?

What doc-type should I pass to get documentation of a class?

我正在尝试检索插槽的文档,但找不到方法。

对于一个简单的class:

(defclass class1 () ((slot1 :documentation "doc")))

(describe 'class1) 能够获取 "doc" 字符串,但是 (documentation 'class1 t)(documentation (find-class 'class1) t) 或我从 hyperspec 尝试的文档函数的任何其他参数找不到同一个文档。我检查了 sbcl 的 describe 函数代码,它在某个时候调用了 (describe-object)。并且调用 (describe-object 'class1 nil) 也会提供正确的信息。

是否有标准定义的方法来获取为 classes 或插槽定义的文档?

例如,如果我想在某个包的每个文档中搜索文本,我会使用特定于实现的函数吗?

我加重了@RainerJoswig 的信息,他在 and this 中给出了类似的问题。归功于他!

洞穴: 这个答案适用于 clisp 和 sbcl。我没有测试的其他实现。 根据 ,它应该也适用于 Clozure CL。

如果您在不同的实现中遇到问题, 您所要做的就是通过 (apropos 'slot-definition-name)(apropos 'class-slots) 顺便检查一下。 (apropos 'class-direct-slots) 其中 package/namespace 这些关键函数都是,并像我在这里所做的那样,在定义中为特定实现添加了 #+<implementationname> 子句。 slot-definition-nameclass-slots btw class-direct-slots 是 CLOS 的元对象协议 (MOP) 的函数。它们可用的地方是特定于实现的。

(defun slot-doc (class slot)
  (let* ((slots #-sbcl(class-slots (find-class class))
                #+sbcl(sb-mop:class-direct-slots (find-class class)))
         (i (position slot #-sbcl(mapcar #'slot-definition-name slots)
                           #+sbcl(mapcar #'sb-mop:slot-definition-name slots)))
         (slot-obj (elt slots i)))
    (documentation slot-obj t)))

;; usage:
(defclass class1 () ((slot1 :documentation "doc")))
(slot-doc 'class1 'slot1)
;; "doc"

因此,例如在 sbcl 中,您可以获得所有插槽的文档:

(mapcar (lambda (s) (documentation s t)) (sb-mop:class-direct-slots (find-class 'class1))

sb-mop:class-slots 在 sbcl 中做了一些不同的事情。似乎是 "false-friend" for class-slots.

为了不必引用 class 和插槽符号, 你可以用它制作一个宏:

(defmacro slot-documentation (class slot)
  `(let* ((slots #-sbcl(class-slots (find-class ',class))
                 #+sbcl(sb-mop:class-direct-slots (find-class ',class)))
          (i (position ',slot #-sbcl(mapcar #'slot-definition-name slots)
                              #+sbcl(mapcar #'sb-mop:slot-definition-name slots)))
          (slot-obj (elt slots i)))
    (documentation slot-obj t)))

;; usage:
(defclass class1 () ((slot1 :documentation "doc")))
(slot-documentation class1 slot1)
;; "doc"

DOCUMENTATION 备注:

This standard prescribes no means to retrieve the documentation strings for individual slots specified in a defclass form, but implementations might still provide debugging tools and/or programming language extensions which manipulate this information. Implementors wishing to provide such support are encouraged to consult the Metaobject Protocol for suggestions about how this might be done.

但是,这是一个通用函数,可以通过符合规范的实现或符合规范的程序的方法进行扩展。这就是 Lispworks、SBCL、CCL、ABCL 和 ECL(以及其他)所做的。您通常可以期望 documentation 专用于 standard-slot-definition class 和 (eql t) 文档类型。

然后,只需访问插槽定义并获取其文档即可:

(ql:quickload :closer-mop)
(in-package :closer-common-lisp)

(defclass class1 () ((slot1 :documentation "doc")))

(documentation (find 'slot1 
                     (class-direct-slots (find-class 'class1))
                     :key #'slot-definition-name)
               t)
=> "doc"