다음과 같은 이름의 파일이 있다고 가정합니다 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
이 파일을로드 한 다음 스크래치 버퍼로 이동하여 다음을 실행합니다.
(setq lexical-binding t)
(f1 5)
(let ((my-dynamic-var 5))
(f2))
(f1 5)
예상대로 5를 반환하여 본문이 예상대로 동적 범위 변수로 f1
취급 my-dynamic-var
되고 있음을 나타냅니다 . 그러나 마지막 양식은 my-dynamic-var
이 변수에 대해 어휘 범위를 사용하고 있음을 나타내는 void-variable 오류를 나타냅니다. 이것은에 대한 문서와 상충되는 것으로 보입니다 defvar
.
이
defvar
형식은 또한 변수를 "special"으로 선언하므로lexical-binding
t가 더라도 항상 동적으로 바인딩됩니다 .
defvar
테스트 파일에서 양식을 변경하여 초기 값을 제공하면 문서에서 말하는 것처럼 변수가 항상 동적으로 처리됩니다. 변수의 범위 지정이 변수 defvar
를 선언 할 때 초기 값이 제공 되었는지 여부에 의해 결정되는 이유를 누구나 설명 할 수 있습니까 ?
중요한 경우 오류 역 추적은 다음과 같습니다.
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)