Avalie docstring em macros

Sep 27 2020

Macros como defun(ou defmacroela mesma) têm um docstringargumento opcional , mas como são macros e não funções, docstringnão são avaliadas, mas são consideradas como estão.

Preciso docstringque seja avaliado para que, em vez de algo assim -

"does a, then b, then c" ; b is hardcoded

Posso colocar algo assim em seu lugar -

(concat "does a, then " (getenv "<some-shell-variable>") " , then c") ; b isn't hardcoded

É possível fazer isso sem ter que ajustar as definições de defune defmacro?

Por tweak, não quero dizer sobrescrever as definições, mas escrever novas macros como prefix-defune com prefix-defmacrobase nas definições existentes de defune demacro, exceto, a docstring é avaliada substituindo todas as instâncias de docstringpor (eval docstring).

Respostas

1 Drew Sep 28 2020 at 03:33

Você pode definir a string doc de qualquer função, variável ou face para qualquer string que desejar, seja (gerada dinamicamente ou não).

Para uma função foo, coloque a string desejada no símbolo foocomo o valor da propriedade function-documentation:

(defun foo () ; `foo' gets no doc string from this defun.
  (interactive)
  (message "FOOOOOOOO"))

(put 'foo 'function-documentation "I'm `foo'.") ; Give function `foo' a doc string.
(put 'foo 'function-documentation "I'm NEW `foo' doc.") ; Redefine the doc string.

A mesma coisa para um defvar ou defcustom - use a propriedade de símbolo variable-documentation:

(defvar foo 42) ; Variable `foo' has no doc string.

(put 'foo 'variable-documentation "I'm `foo'.") ; Give var `foo' a doc string.
(put 'foo 'variable-documentation "I'm NEW `foo' .") ; Redefine the doc string.

Veja o manual Elisp, nó Documentation Basics e seus subnós.

Mesma coisa para defface- usar propriedade de símbolo variable-documentation. Mas deffacerequer uma string doc. No entanto, você pode alterá-lo dinamicamente, como pode fazer para uma função ou variável.

(defface foo '((t :foreground "Red")) "0000") ; Doc string "0000".

(put 'foo 'face-documentation "11111") ; Change doc string to "1111".
2 phils Sep 27 2020 at 19:47
(defun foo ()
  (:documentation (concat "does a, then " (getenv "<some-shell-variable>") " , then c"))
  ...BODY...)

Esta é efetivamente uma duplicata de É possível anexar a string doc gerada a um lambda? exceto que essa pergunta é muito lambdaorientada, então a resposta de Stefan não indica que você pode fazer a mesma coisa com defun.

Se você precisa que a docstring seja disponibilizada evalsob demanda (ou seja, toda vez que você solicitá-la), você também pode fazer isso, mas aparentemente não com :documentation. Consulte minha resposta à pergunta anterior para algumas opções para fazer isso.