เช่นเดียวกับคำตอบอื่น ๆ ที่บอกว่านี่เป็นเพียงวิธีที่ defvar ทำงาน แต่คุณสามารถหลีกเลี่ยงได้นี่คือ elisp หลังจากทั้งหมด
คุณสามารถกำหนดวิธีการทำงานของ defvar ได้ชั่วคราวหากคุณต้องการและในช่วงเวลานั้นให้โหลดแพ็กเกจที่คุณต้องการรีเซ็ต
ฉันเขียนมาโครซึ่งในระหว่างการประเมินร่างกายค่า defvars จะถูกประเมินใหม่เสมอ
(defmacro my-fake-defvar (name value &rest _)
"defvar impersonator that forces reeval."
`(progn (setq ,name ,value)
',name))
(defmacro with-forced-defvar-eval (&rest body)
"While evaluating, any defvars encountered are reevaluated"
(declare (indent defun))
(let ((dv-sym (make-symbol "old-defvar")))
`(let ((,dv-sym (symbol-function 'defvar)))
(unwind-protect
(progn
(fset 'defvar (symbol-function 'my-fake-defvar))
,@body)
(fset 'defvar ,dv-sym)))))
ตัวอย่างการใช้งาน:
file_a.el
(defvar my-var 10)
file_b.el
(with-forced-defvar-eval
(load-file "file_a.el")
(assert (= my-var 10))
(setq my-var 11)
(assert (= my-var 11)
(load-file "file_a.el")
(assert (= my-var 10))
หมายเหตุ:สิ่งนี้ควรใช้เพื่อจุดประสงค์ในการประเมิน defvars อีกครั้งเนื่องจากเป็นการละเว้นการทำเอกสารเมื่อทำการประเมินใหม่ คุณสามารถปรับเปลี่ยนแมโครเพื่อรองรับการประเมินใหม่ที่ใช้เอกสารได้เช่นกัน แต่ฉันจะปล่อยให้เป็นเช่นนั้น
ในกรณีของคุณคุณสามารถทำได้
(with-forced-defvar-eval (require 'some-package))
แต่รู้ว่าคนที่เขียน elisp คาดหวังว่า defvar จะทำงานตามที่ระบุมันอาจเป็นได้ว่าพวกเขาใช้ defvar เพื่อกำหนดและ setq ในฟังก์ชั่น init บางตัวเพื่อระบุค่าดังนั้นคุณอาจสิ้นสุดตัวแปรที่คุณไม่ต้องการ นี่อาจเป็นของหายาก
การดำเนินการทางเลือก
การใช้สิ่งนี้คุณสามารถกำหนด defvar ใหม่ได้ทั่วโลกและควบคุมว่าจะกำหนดค่าของสัญลักษณ์เป็น ARIT-VALUE แม้ว่าจะมีการกำหนดสัญลักษณ์โดยการเปลี่ยนค่าของdefvar-always-reeval-values
สัญลักษณ์ใหม่ก็ตาม
;; save the original defvar definition
(fset 'original-defvar (symbol-function 'defvar))
(defvar defvar-always-reeval-values nil
"When non-nil, defvar will reevaluate the init-val arg even if the symbol is defined.")
(defmacro my-new-defvar (name &optional init-value docstring)
"Like defvar, but when `defvar-always-reeval-values' is non-nil, it will set the symbol's value to INIT-VALUE even if the symbol is defined."
`(progn
(when defvar-always-reeval-values (makunbound ',name))
(original-defvar ,name ,init-value ,docstring)))
;; globally redefine defvar to the new form
(fset 'defvar (symbol-function 'my-new-defvar))
makunbound
แล้วประเมินอีกครั้งรหัสในบัฟเฟอร์