Angenommen, ich habe eine Datei mit dem Namen elisp-defvar-test.el
:
;;; 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
Ich lade diese Datei und gehe dann in den Arbeitspuffer und starte:
(setq lexical-binding t)
(f1 5)
(let ((my-dynamic-var 5))
(f2))
(f1 5)
Gibt wie erwartet 5 zurück, was darauf hinweist, dass der Body von wie erwartet als Variable mit dynamischem Gültigkeitsbereich f1
behandelt wird my-dynamic-var
. Das letzte Formular gibt jedoch einen Void-Variablenfehler für an my-dynamic-var
, der angibt, dass für diese Variable ein lexikalischer Gültigkeitsbereich verwendet wird. Dies scheint im Widerspruch zu der Dokumentation zu stehen defvar
, die besagt:
Das
defvar
Formular deklariert die Variable auch als "speziell", so dass sie immer dynamisch gebunden ist, auch wennlexical-binding
t ist.
Wenn ich das defvar
Formular in der Testdatei so ändere , dass ein Anfangswert angegeben wird, wird die Variable immer als dynamisch behandelt, wie in der Dokumentation angegeben. Kann jemand erklären, warum der Umfang einer Variablen davon abhängt, ob defvar
bei der Deklaration dieser Variablen ein Anfangswert angegeben wurde oder nicht ?
Hier ist die Fehlerrückverfolgung, falls es darauf ankommt:
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)