Misalkan saya memiliki file bernama elisp-defvar-test.elmengandung:
;;; elisp-defvar-test.el --- -*- lexical-binding: t -*-
(defvar my-dynamic-var)
(defun f1 (x)
"Should return X."
(let ((my-dynamic-var x))
(f2)))
(defun f2 ()
"Returns the current value of `my-dynamic-var'."
my-dynamic-var)
(provide 'elisp-dynamic-test)
;;; elisp-defvar-test.el ends here
Saya memuat file ini dan kemudian pergi ke buffer awal dan menjalankan:
(setq lexical-binding t)
(f1 5)
(let ((my-dynamic-var 5))
(f2))
(f1 5)mengembalikan 5 seperti yang diharapkan, menunjukkan bahwa tubuh f1memperlakukan my-dynamic-varsebagai variabel cakupan dinamis, seperti yang diharapkan. Namun, formulir terakhir memberikan kesalahan variabel void my-dynamic-var, yang menunjukkan bahwa ia menggunakan pelingkupan leksikal untuk variabel ini. Ini sepertinya bertentangan dengan dokumentasi untuk defvar, yang mengatakan:
The
defvarbentuk juga menyatakan variabel sebagai "khusus", sehingga selalu dinamis terikat bahkan jikalexical-bindingadalah t.
Jika saya mengubah defvarformulir dalam file pengujian untuk memberikan nilai awal, maka variabel selalu diperlakukan sebagai dinamis, seperti yang dikatakan dokumentasi. Adakah yang bisa menjelaskan mengapa pelingkupan suatu variabel ditentukan oleh apakah defvardiberi nilai awal atau tidak saat mendeklarasikan variabel itu?
Inilah backtrace kesalahan, jika itu penting:
Debugger entered--Lisp error: (void-variable my-dynamic-var)
f2()
(let ((my-dynamic-var 5)) (f2))
(progn (let ((my-dynamic-var 5)) (f2)))
eval((progn (let ((my-dynamic-var 5)) (f2))) t)
elisp--eval-last-sexp(t)
eval-last-sexp(t)
eval-print-last-sexp(nil)
funcall-interactively(eval-print-last-sexp nil)
call-interactively(eval-print-last-sexp nil nil)
command-execute(eval-print-last-sexp)