是否可以将生成的文档字符串附加到lambda?


10

Emacs文档说,当文档字符串放在其中lambdadefun“直接存储在函数对象中”时。但是,我们可以像这样更改命名函数的文档:

(put 'my-function-name 'function-documentation "Blah.")

但是,相同的技巧不适用于lambda。有没有一种方法可以向lambda添加文档?还是以某种方式动态生成文档字符串文字?

为了澄清,设想以下情况:

(let ((foo 1)
      (bar 2))
  (lambda ()
    (+ foo bar)))

我希望Lambda有一个文档字符串,其中提到fooand的值bar

Answers:


12

好的lambda可以像其他函数定义一样具有常规的文档字符串:

(lambda ()
   "I'm a docstring!"
   (+ foo bar))

因此,您可以使用:

(let ((foo 1)
      (bar 2))
  `(lambda ()
     ,(format "Function which sums foo=%s and bar=%s" foo bar)
     (+ foo bar)))

为什么要在匿名函数上使用文档字符串是另一个问题,这可能会影响您采用的方法。

例如,如果您打算将其绑定到键上并希望C-h k显示该帮助,则可以使用这种方法,但是该帮助仍会显示功能对象本身(包括文档字符串),但并非如此。大; 不过你可以做到这一点,你(也)看到很好的格式化的版本:

(global-set-key
 (kbd "C-c a")
 (let ((foo 1)
       (bar 2))
   `(lambda ()
      ,(format "Function which sums foo=%s and bar=%s" foo bar)
      (interactive)
      (+ foo bar))))

但是,您可能更喜欢使用符号。您可以将匿名函数与未插入的符号配对,而不必担心它会与任何其他同名符号冲突。这将使帮助变得更干净,因为它将显示符号名称而不是功能对象。在这种情况下,我们可以选择将docstring传递给,defalias而不是将其嵌入lambda形式。

(global-set-key
 (kbd "C-c a")
 (let ((foo 1)
       (bar 2))
   (defalias (make-symbol "a-foo-bar-function")
     (lambda ()
       (interactive)
       (+ foo bar))
     (format "Function which sums foo=%s and bar=%s" foo bar))))

或(这几乎是同一件事),您可以捕获原始的符号,并按照原始代码直接设置symbol属性:

(global-set-key
 (kbd "C-c a")
 (let ((foo 1)
       (bar 2)
       (sym (make-symbol "a-foo-bar-function")))
   (put sym 'function-documentation
        (format "Function which sums foo=%s and bar=%s" foo bar))
   (defalias sym
     (lambda ()
       (interactive)
       (+ foo bar)))))

作为一个侧面说明,要知道,这个功能将被用于相加松懈约束值foobar如果您使用的lexical-binding: t是你的库。如果foo和bar动态绑定,则我生成的文档字符串很可能在运行时不准确。不过,我们实际上可以使用动态文档字符串来满足这种情况。信息节点(elisp) Accessing Documentationdocumentation-property

如果属性值不是'nil',不是字符串,并且不引用文件中的文本,则将其作为Lisp表达式求值以获得字符串。

因此,使用任何基于符号的方法,我们都可以引用文档表格,以便在调用时对其进行评估:

(defalias (make-symbol "a-foo-bar-function")
   (lambda ()
     (interactive)
     (+ foo bar))
   '(format "Function which sums foo=%s and bar=%s" foo bar))

13

在Emacs-25中,有一个专门用于此目的的新功能:

(let ((foo 1)
      (bar 2))
  (lambda ()
    (:documentation (format "Return the sum of %d and %d." foo bar))
    (+ foo bar)))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.