Imagine que eu tenho os seguintes arquivos no meu pacote (ridículo):
Arquivo test1.el
:
;;; test1.el ---
;;; Code:
(defvar test-var1)
(defun test-fun1 (test)
nil)
(require 'test2 "./test2.el)
(provide 'test1)
;;; test1.el ends here
Arquivo test2.el
:
;;; test2.el ---
;;; Code:
(defun test-fun2 ()
(let ((test test-var1))
(test-fun1 test)))
(provide 'test2)
;;; test2.el ends here
Se então eu corro:
emacs -batch -f batch-byte-compile *.el
Eu recebo o seguinte resultado:
Compiling .../test1.el...
Wrote .../test1.elc
Compiling .../test2.el...
In test-fun2:
test2.el:9:15:Warning: reference to free variable `test-var1'
In end of data:
test2.el:14:1:Warning: the function `test-fun1' is not known to be defined.
Wrote .../test2.elc
Entendo por que esses avisos aparecem e entendo que são apenas avisos. No entanto, seria fácil perder um erro de digitação no nome de uma função ignorando todos os avisos desse tipo.
De alguma forma, pensei que adicionar uma (require 'test2)
linha test2.el
deveria corrigi-lo. No entanto, neste caso, recebo:
Compiling .../test1.el...
In toplevel form:
test1.el:10:1:Error: Recursive `require' for feature `test2'
Compiling .../test2.el...
In toplevel form:
test2.el:5:1:Error: Recursive `require' for feature `test1'
Isso é enigmático, porque pensei que o objetivo require
era exatamente evitar carregamento recursivo. Eu suponho que require
esteja se comportando como load
durante o tempo de compilação.
Qual é uma maneira boa (e segura) de se livrar desses avisos?
O manual fornece uma solução alternativa (eu a coloco como uma resposta melhor do que nada abaixo), mas, no final das contas, gostaria que a solução fosse bastante automática (não exigindo que eu listasse todas as funções e variáveis necessárias em cada arquivo).
A solução ideal seria incorporada no emacs ou fornecida com o Cask. Se não existir, aceitarei o que está disponível, é claro.
fonte
-mode
função). O exemplo é um exemplo de brinquedo, usá-lotest-fun2
não mudaria o problema.test-variables
), e esse arquivo não precisará exigir nenhum dos outros.eval-when-compile
's' e os pacotes precisarão definir sua variávelnil
no final do arquivo (porque todos os arquivos são compilados em uma única sessão). Também tem o benefício de me mostrar por que o carregamento exatamente recursivo é mais complicado de evitar do que o carregamento repetido.Seu exemplo é estranho:
require
test2 no final do test1, enquantorequire
que "sempre" deve estar no início de um arquivo.require
é desnecessário); e OTOH seu test2 chama as funções test1, portanto, precisa do test1, mas falharequire
nele.Como você
require
está atrasado.fonte
test1
claro que usaria as funções definidas portest2
e o pacote seria carregado apenas atravéstest1
(através de carregamento automático). Esta resposta não deveria ser um comentário? É apenas salientar que meu exemplo é mal escolhido e, de outra forma, não fornece uma resposta para a pergunta.O manual sugere adição
declare-function
edefvar
linhas.O
test2
arquivo resultante é:No entanto, isso precisa ser feito para todas as funções e todas as variáveis definidas nos arquivos "principais".
fonte