【问题标题】:What doc-type should I pass to get documentation of a class?我应该通过什么文档类型来获取类的文档?
【发布时间】:2020-08-31 11:47:47
【问题描述】:

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

对于一个简单的类:

(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) 也会提供正确的信息。

是否有标准定义的方式来获取为类或槽定义的文档?

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

【问题讨论】:

标签: common-lisp


【解决方案1】:

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

洞穴: 这个答案适用于 clisp 和 sbcl。我没有测试的其他实现。 根据Rainer's answer,它应该也可以在 Clozure CL 中使用。

如果您在不同的实现中遇到问题, 您所要做的就是通过(apropos 'slot-definition-name)(apropos 'class-slots) 顺便检查一下。 (apropos 'class-direct-slots) 这些关键功能都在哪个包/命名空间中,并像我在这里所做的那样,将特定实现的 #+<implementationname> 子句添加到定义中。 slot-definition-name, class-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 中做了一些不同的事情。似乎是class-slots 的“假朋友”。

为了不必引用类和槽符号, 你可以用它做一个宏:

(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"

【讨论】:

  • 很难在这个或 coredump 的响应之间做出选择。他们都很好地回答了这个问题。感谢您提供详细信息。
  • @AlbusMPiroglu 是的,但我也同意他的回答更好,更干净。欢迎!
【解决方案2】:

DOCUMENTATION 备注:

该标准没有规定检索以 defclass 形式指定的各个插槽的文档字符串的方法,但实现仍可能提供调试工具和/或操作此信息的编程语言扩展。鼓励希望提供此类支持的实施者咨询元对象协议以获取有关如何完成此操作的建议。

但是,这是一个通用函数,可以通过方法扩展,无论是通过一致的实现还是一致的程序。这就是 Lispworks、SBCL、CCL、ABCL 和 ECL 所做的(以及其他)。您通常可以期望 documentation 专门用于 standard-slot-definition 类和 (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"

【讨论】:

  • 我在问自己是否有一些包可以通过 MOP 进行更统一的访问。感谢您的解决方案,@coredump!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 2023-04-03
  • 2011-02-08
  • 1970-01-01
相关资源
最近更新 更多