È possibile collegare una stringa doc generata a un lambda?


10

I documenti di Emacs affermano che quando la stringa di documenti viene inserita lambdao defunè "memorizzata direttamente nell'oggetto funzione". Tuttavia, possiamo modificare i documenti delle funzioni con nome in questo modo:

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

Ma lo stesso trucco non funziona con le lambda. C'è un modo per aggiungere documentazione a lambda? O in qualche modo generare dinamicamente letterale stringa di documenti?

Per chiarire, immagina la seguente situazione:

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

Vorrei che la lambda avesse una stringa doc che menziona i valori di fooe bar.

Risposte:


12

Beh, lambda può avere normali dotstring proprio come qualsiasi altra definizione di funzione:

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

Quindi potresti usare:

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

Perché vuoi una spiegazione su una funzione anonima è un'altra domanda, che potrebbe influenzare l'approccio che adotti.

Ad esempio, se stai pianificando di associarlo a una chiave e desideri C-h kvisualizzare tale aiuto, puoi utilizzare questo approccio, ma ovviamente l'aiuto visualizzerà anche l'oggetto funzione stesso (docstring incluso), che non è così grande; tuttavia potresti farlo e vedresti (anche) la versione ben formattata:

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

Tuttavia, potresti preferire l'uso di un simbolo. È possibile associare una funzione anonima con una uninterned simbolo, e non ti preoccupare in conflitto con eventuali altri simboli con lo stesso nome. Questo rende l'aiuto più pulito, poiché visualizzerà il nome del simbolo anziché l'oggetto funzione. In questo caso abbiamo la possibilità di passare il docstring defaliasinvece di incorporarlo nella forma 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))))

oppure (e questa è praticamente la stessa cosa) potresti catturare il simbolo non interessato e impostare direttamente la proprietà del simbolo, secondo il tuo codice originale:

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

Come nota a margine, essere consapevoli che questa funzione è solo sta per essere sommando i valori Let-bound per fooe barse si sta utilizzando lexical-binding: tper la vostra biblioteca. Se foo e bar sono associati dinamicamente, i documenti che ho generato probabilmente non sarebbero accurati in fase di esecuzione. Tuttavia, possiamo effettivamente soddisfare questa situazione con dotstrings dinamici . Il nodo informativo (elisp) Accessing Documentationdice di documentation-property:

Se il valore della proprietà non è 'nil', non è una stringa e non fa riferimento al testo in un file, viene valutato come espressione Lisp per ottenere una stringa.

Quindi, con uno qualsiasi degli approcci basati sui simboli, potremmo citare il modulo di documentazione per poterlo valutare al momento della chiamata:

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

13

In Emacs-25, c'è una nuova funzionalità esattamente per questo scopo:

(let ((foo 1)
      (bar 2))
  (lambda ()
    (:documentation (format "Return the sum of %d and %d." foo bar))
    (+ foo bar)))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.