Quiero obtener el efecto de una variable estática usando defun
dentro de un let
enlace léxico para crear un cierre. Sin embargo, al compilar byte el archivo, recibo una advertencia. ¿Estoy haciendo algo mal, o si no, hay alguna forma de suprimir esta advertencia?
He creado un MCVE:
;; -*- lexical-binding: t -*-
(let ((count 0))
(defun increase-count ()
(interactive)
(setq count (1+ count))
(message "Count is: %d" count))
;; The warning happens here.
(increase-count))
El código funciona como se esperaba: la función increase-count
imprime "Count is: n" donde n aumenta cada vez que se llama. Sin embargo, al compilar byte este archivo, aparece la siguiente advertencia:
In end of data:
mcve.el:11:1:Warning: the function ‘increase-count’ is not known to be
defined.
Me parece que increase-count
siempre debe definirse antes de que se llame al final del let-block. ¿No es este el caso?
byte-compilation
lexical-scoping
defun
lexical-binding
Will Kunkel
fuente
fuente
defun
no hace lo que crees que hace, siempre crea una definición de nivel superior. Elisp es después de todo no Esquema ...Respuestas:
La forma del compilador de bytes para decidir si una función se definirá o no es muy "ingenua" y se deja engañar incluso en su caso "obvio". Pero puede escribirlo de una manera que permita al compilador comprender lo que sucede:
Por supuesto, aún mejor sería mejorar la lógica del compilador de bytes: los parches son bienvenidos para eso.
fuente
Para suprimir la advertencia del compilador de bytes, intente agregar esto antes de su código, comenzando en la columna 0 (más a la izquierda):
C-h f declare-function
Te dijo:fuente
FILEONLY
argumento no nulo para el caso en cuestión? Por cierto, habría dado la misma respuesta ;-).FILEONLY
no parecía ser necesario aquí, para mí. Lo cual parece indicar quecheck-declare
reconocef
yg
defunde.f
yg
solo tiene sentido en el contexto de emacs.stackexchange.com/q/39439 ?FILEONLY
no parecía ser necesario aquí, para mí. Lo cual parecería indicar quecheck-declare
reconoce elincrease-count
defun. ;-)Creo que colocar la definición en cuestión
eval-and-compile
también lograría superficialmente el mismo resultado que en la respuesta correcta de Stefan :Sin embargo, apenas estoy familiarizado con las sutilezas del uso
eval-and-compile
y, además, no espero que este enfoque sea de ninguna manera superior.fuente