Ao executar o seguinte, recebo um erro:
(defun caller (func)
(url-retrieve "http://m0smith.freeshell.org/"
(lambda (status) (funcall func))))
(caller (lambda() (message "called")))
Resultado:
error in process filter: Symbol's value as variable is void: func
Qual é a melhor maneira de resolver este problema? Basicamente, preciso aceitar um retorno de chamada de outro lugar, envolvê-lo em outro lambda e usá-lo como retorno de chamada para recuperar url.
Se eu mudar o chamador para
(defun caller (func)
(url-retrieve "http://m0smith.freeshell.org/"
`(lambda (status) (funcall ,func))))
funciona. No entanto, não posso fazer isso, pois o func está sendo passado pelo flycheck e a expansão de macro o interrompe. Para ver o contexto completo do que estou fazendo: https://gist.github.com/m0smith/b5961fda6afd71e82983
flycheck
lexical-scoping
M Smith
fonte
fonte
lexical-let
ou configuração de variávellexical-binding
. Por favor, esclareça qual é o problema com a "macro" não mostrada.FUNC
além dofuncall
que logicamente, você não precisará de ligação lexical aqui. Não há nada errado em usá-lo, mas você não precisa , a menos que algum código realmente precise fazer uso da variávelFUNC
. Se você não precisar dele (como é a aparência até agora), substitua a ocorrência pelo valor, usando aspas por vírgula.lexical-let
. A variável globallexical-binding
está disponível no Emacs 24.Respostas:
Você pode conseguir isso localmente usando lexical-let do cl.el :
Para ser explícito, como diz a ajuda:
Agora você pode obter o mesmo efeito ativando a ligação lexical que foi adicionada no Emacs 24.1. Esta é uma variável local do buffer que pode ser definida e permitirá fechamentos lexicais em todo o código no buffer. Portanto, seu buffer ficaria assim:
fonte
my-test-caller: Symbol's function definition is void: lexical-let
no meu emacs: GNU Emacs 24.4.1 (x86_64-w64-mingw32) `of 2014-10-20 on KAELlexical-let
é definido emcl-macs.el
. Então(eval-when-compile '(require 'cl))
cl.el
em tempo de execução, apenas para isso.lexical-let
é uma macro, portanto é suficiente exigir isso em tempo de compilação.lexical-binding
. O Flycheck não suporta o Emacs 23 de qualquer maneira, então não faz sentido tentar ser compatível com ele.Ative
lexical-binding
para sua biblioteca, comM-x add-file-local-variable-prop-line RET lexical-binding RET t
.Por favor, não use
lexical-let
como sugerido pela outra resposta. O Flycheck em si não é compatível com o Emacs 23, portanto, não faz sentido tentar manter a compatibilidade do Emacs 23 em seu próprio código.fonte
lexical-binding
não há necessidade de uma ligação adicional, porque o argumento em si tem um escopo lexicamente. Além disso,lexical-binding
cria verdadeiros fechamentos, enquantolexical-let
usa símbolos não internos para emular a ligação lexical.let
ligação dinâmica de variáveis indefinidas. Mas, novamente, Flycheck é para o Emacs 24 de qualquer maneira, por isso não estamos falando de código legado.