Eu quero obter o efeito de uma variável estática usando defun
dentro de let
com ligação lexical para criar um fechamento. No entanto, ao compilar o arquivo com bytes, recebo um aviso. Estou fazendo algo errado, ou se não, existe uma maneira de suprimir esse aviso?
Eu criei um 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))
O código funciona como esperado: a função increase-count
exibe "Count is: n", em que n aumenta sempre que é chamado. No entanto, ao compilar este arquivo por byte, recebo o seguinte aviso:
In end of data:
mcve.el:11:1:Warning: the function ‘increase-count’ is not known to be
defined.
Parece-me que increase-count
sempre deve ser definido antes de ser chamado no final do bloco let. Não é este o caso?
byte-compilation
lexical-scoping
defun
lexical-binding
Will Kunkel
fonte
fonte
defun
não faz o que você pensa que faz, sempre cria uma definição de nível superior.Respostas:
A maneira do compilador de bytes de decidir se uma função será definida ou não é muito "ingênua" e é enganada, mesmo no seu caso "óbvio". Mas você pode escrever de uma maneira que permita ao compilador entender o que acontece:
Obviamente, o melhor seria melhorar a lógica do compilador de bytes: os patches são bem-vindos para isso.
fonte
Para suprimir o aviso do compilador de bytes, tente adicioná-lo antes do seu código, começando na coluna 0 (mais à esquerda):
C-h f declare-function
diz lhe:fonte
FILEONLY
argumento não nulo é necessário para o caso em questão? Entre, eu teria dado a mesma resposta ;-).FILEONLY
não parecia ser necessário aqui, para mim. O que parece indicar quecheck-declare
reconhecef
eg
desaprova.f
eg
só faz sentido no contexto de emacs.stackexchange.com/q/39439 ?FILEONLY
não parecia necessário aqui, para mim. O que parece indicar quecheck-declare
reconhece oincrease-count
desfecho. ;-)Acredito que colocar a definição em questão
eval-and-compile
também atingiria superficialmente o mesmo resultado da resposta correta de Stefan :No entanto, mal conheço as sutilezas do uso
eval-and-compile
e, além disso, não espero que essa abordagem seja de alguma forma superior.fonte