Saat menjalankan yang berikut ini saya mendapatkan kesalahan:
(defun caller (func)
(url-retrieve "http://m0smith.freeshell.org/"
(lambda (status) (funcall func))))
(caller (lambda() (message "called")))
Hasil:
error in process filter: Symbol's value as variable is void: func
Apa cara terbaik untuk mengatasi masalah ini? Pada dasarnya saya perlu menerima panggilan balik dari tempat lain, membungkusnya dengan lambda lain dan menggunakannya sebagai panggilan balik untuk mengambil-url.
Jika saya mengubah penelepon ke
(defun caller (func)
(url-retrieve "http://m0smith.freeshell.org/"
`(lambda (status) (funcall ,func))))
berhasil. Namun, saya tidak bisa melakukan ini karena func sedang dilewati oleh flycheck dan ekspansi makro memecahnya. Untuk melihat konteks lengkap dari apa yang saya lakukan: https://gist.github.com/m0smith/b5961fda6afd71e82983
flycheck
lexical-scoping
M Smith
sumber
sumber
lexical-let
atau menyetel variabellexical-binding
. Harap jelaskan apa masalahnya dengan "makro" yang tidak ditampilkan.FUNC
luarfuncall
maka secara logis Anda tidak perlu mengikat leksikal di sini. Tidak ada yang salah dengan menggunakannya, tetapi Anda tidak memerlukannya , kecuali beberapa kode benar-benar perlu menggunakan variabelFUNC
. Jika Anda tidak membutuhkannya (yang terlihat seperti sejauh ini), maka ganti saja kemunculannya dengan nilainya, menggunakan backquote dengan koma.lexical-let
. Variabel globallexical-binding
tersedia dalam Emacs 24.Jawaban:
Anda dapat mencapai ini secara lokal dengan menggunakan lexical-let cl.el :
Secara eksplisit seperti yang dikatakan bantuan:
Sekarang Anda bisa mendapatkan efek yang sama dengan mengaktifkan lexical-binding yang ditambahkan di Emacs 24.1. Ini adalah variabel lokal buffer yang dapat diatur dan akan memungkinkan penutupan leksikal pada semua kode dalam buffer. Jadi buffer Anda akan terlihat seperti ini:
sumber
my-test-caller: Symbol's function definition is void: lexical-let
di emacs saya: GNU Emacs 24.4.1 (x86_64-w64-mingw32) `dari 2014-10-20 di KAELlexical-let
didefinisikan dalamcl-macs.el
. Jadi(eval-when-compile '(require 'cl))
cl.el
saat runtime, hanya untuk ini.lexical-let
adalah makro, jadi cukup untuk membutuhkannya pada waktu kompilasi.lexical-binding
. Flycheck tidak mendukung Emacs 23, jadi tidak ada gunanya mencoba menjadi kompatibel dengan itu.Aktifkan
lexical-binding
untuk perpustakaan Anda, denganM-x add-file-local-variable-prop-line RET lexical-binding RET t
.Tolong jangan gunakan
lexical-let
seperti yang disarankan oleh jawaban lain. Flycheck sendiri tidak kompatibel dengan Emacs 23, jadi tidak ada gunanya mencoba mempertahankan kompatibilitas Emacs 23 dalam kode Anda sendiri.sumber
lexical-binding
tidak ada kebutuhan untuk mengikat tambahan, karena argumen itu sendiri dibatasi secara leksikal. Selain itu,lexical-binding
membuat penutupan benar, sedangkanlexical-let
menggunakan simbol yang tidak diinginkan untuk meniru pengikatan leksikal.let
pengikatan variabel yang tidak terdefinisi secara dinamis. Tetapi sekali lagi, Flycheck adalah untuk Emacs 24, jadi kita tidak berbicara tentang kode warisan.