从.lisp文件生成二进制文件,该文件包含以下定义:
(in-package :xpto)
(defmacro defparam (name init.value)
`(progn
(defvar ,name ,init.value)
(eval-when (:compile-toplevel :load-toplevel :execute)
(export ',name "xpto"))))
(defparam myparam 10)
(defun getparam()
myparam)
所以,我想制作一个补丁文件以覆盖该符号,因此,想到这样的事情:
;; Unintern the given symbol because otherwise we are not able to overwrite it
;; once it was set through defvar
(eval-when (:compile-toplevel :load-toplevel :execute)
(unintern 'xpto::myparam :xpto))
加载补丁文件后,奇怪的行为开始出现:
> :pa xpto
> myparam
>> Error: Attempt to take the value of the unbound variable `myparam'
上面的输出正是我所期待的,但这个让我很烦恼:
> (getparam)
>> 10
我原以为没有返回任何值因为符号不再存在 如何以对任何引用返回上面显示的错误消息的方式删除/取消发送 myparam 符号?
p.s:在补丁文件中运行以下表达式对我来说不是一个有效的选项:
(setf myparam 20)
答案 0 :(得分:4)
当您评估(defun getparam)
时,它会记住符号myparam
,每当您致电(getparam)
时,它都会返回符号值。 myparam
的非内部意味着您无法按名称在包中找到符号,但符号对象仍然存在。
(defvar myparam 10)
(defun getparam() myparam)
#'getparam
==> #<FUNCTION GETPARAM NIL ... (BLOCK GETPARAM MYPARAM)>
(unintern 'myparam)
#'getparam
==> #<FUNCTION GETPARAM NIL ... (BLOCK GETPARAM #:MYPARAM)>
(getparam)
==> 10
请注意,该函数的第二个打印输出包含一个未打开的符号。
如何删除/取消发送myparam符号的方式,对它的任何引用都会返回上面显示的错误信息?
没有办法 - 除了重新定义getparam
。
但是,您可以不同地定义getparam
:
(defvar myparam 10)
(defun getparam()
(symbol-value (or (find-symbol "MYPARAM")
(error "Symbol MYPARAM does not exist"))))
(getparam)
==> 10
(unintern 'myparam)
(getparam)
*** - Symbol MYPARAM does not exist
答案 1 :(得分:3)
您还可以将符号设为未绑定:
CL-USER 4 > (defvar foosym 10)
FOOSYM
CL-USER 5 > foosym
10
CL-USER 6 > (makunbound 'foosym)
FOOSYM
CL-USER 7 > foosym
Error: The variable FOOSYM is unbound.