Valuta docstring nelle macro

Sep 27 2020

Le macro come defun(o defmacrose stesse) hanno un docstringargomento opzionale , ma poiché sono macro e non funzioni, docstringnon vengono valutate, ma vengono prese così come sono.

Ho bisogno docstringche venga valutato in modo che invece di qualcosa del genere -

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

Posso mettere qualcosa del genere invece -

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

È possibile farlo senza dover modificare le definizioni di defune defmacro?

Con tweak, non intendo sovrascrivere le definizioni, ma scrivere nuove macro come prefix-defune in prefix-defmacrobase alle definizioni esistenti di defune demacro, ad eccezione, la docstring viene valutata sostituendo tutte le istanze di docstringcon (eval docstring).

Risposte

1 Drew Sep 28 2020 at 03:33

Puoi impostare la doc string di qualsiasi funzione, variabile o faccia su qualsiasi stringa tu voglia, indipendentemente dal fatto che (generata dinamicamente o meno).

Per una funzione foo, inserisci la stringa che desideri sul simbolo foocome valore della proprietà 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.

Stessa cosa per defvar o defcustom - usa la proprietà symbol 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.

Vedere il manuale Elisp, Nozioni di base sulla documentazione del nodo e i suoi sottonodi.

Stessa cosa per defface- usa la proprietà del simbolo variable-documentation. Ma deffacerichiede una doc string. Puoi comunque cambiarlo dinamicamente, come puoi per una funzione o una variabile.

(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...)

Questo è effettivamente un duplicato di È possibile allegare la doc string generata a un lambda? tranne che quella domanda è molto lambdaorientata, e quindi la risposta di Stefan non indica che puoi fare la stessa cosa con defun.

Se hai bisogno che la docstring sia evalsu richiesta (cioè ogni volta che la richiedi), puoi farlo anche tu, ma a quanto pare non con :documentation. Fare riferimento alla mia risposta alla domanda precedente per alcune opzioni per farlo.