elisp – ¿Es posible adjuntar una cadena de documentos generada a una lambda?

Pregunta:

Los documentos de Emacs dicen que cuando la cadena de documentos se coloca dentro de lambda o defun se "almacena directamente en el objeto de función". Sin embargo, podemos cambiar documentos de funciones nombradas como esta:

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

Pero el mismo truco no funciona con lambdas. ¿Hay alguna forma de agregar documentación a lambda? ¿O de alguna manera generar dinámicamente un literal de cadena de documentos?

Para aclarar, imagine la siguiente situación:

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

Me gustaría que la lambda tuviera una cadena de documentos que mencione los valores de foo y bar .

Respuesta:

Bueno, las lambdas pueden tener cadenas de documentos regulares como cualquier otra definición de función:

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

Entonces podrías usar:

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

Por qué desea una cadena de documentos en una función anónima es otra pregunta, que podría afectar el enfoque que adopte.

Por ejemplo, si planea vincularlo a una tecla y desea que Ch k muestre esa ayuda, puede usar este enfoque, pero, por supuesto, la ayuda también mostrará el objeto de función en sí (docstring incluido), que no es ' t tan genial; sin embargo, se podía hacer esto y que se vería (también) la versión formateada bien-:

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

Sin embargo, es posible que prefiera utilizar un símbolo. Puede emparejar una función anónima con un símbolo no internado y no preocuparse de que entre en conflicto con otros símbolos del mismo nombre. Esto hace que la ayuda sea más limpia, ya que mostrará el nombre del símbolo en lugar del objeto de función. En esta instancia, tenemos la opción de pasar la cadena de defalias a defalias lugar de incrustarla en la 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))))

o (y esto es prácticamente lo mismo) puede capturar el símbolo no internado y establecer la propiedad del símbolo directamente, según su código original:

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

Como nota al margen, tenga en cuenta que esta función solo va a sumar los valores let-bound para foo y bar si está utilizando lexical-binding: t para su biblioteca. Si foo y bar están vinculados dinámicamente, lo más probable es que las cadenas de documentos que he generado no sean precisas en tiempo de ejecución. Sin embargo, podemos atender esa situación con cadenas de documentación dinámicas . El nodo de información (elisp) Accessing Documentation dice de documentation-property de documentation-property :

Si el valor de la propiedad no es 'nil', no es una cadena y no se refiere al texto de un archivo, entonces se evalúa como una expresión Lisp para obtener una cadena.

Entonces, con cualquiera de los enfoques basados ​​en símbolos, podríamos citar el formulario de documentación para que se evalúe en el momento de la llamada:

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

Leave a Comment

Your email address will not be published.

Scroll to Top

istanbul avukat

-

web tasarım