2

二进制文件是从包含以下定义的 .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符号?

ps:在补丁文件中运行以下表达式对我来说不是一个有效的选项:

(setf myparam 20)
4

2 回答 2

4

当您评估(defun getparam)时,它会记住符号myparam,并且每当您调用时(getparam),它都会返回符号值。uninterning ofmyparam意味着您无法通过名称在包中找到符号,但符号对象仍然存在。

(defvar myparam 10)
(defun getparam() myparam)
#'getparam
==> #<FUNCTION GETPARAM NIL ... (BLOCK GETPARAM MYPARAM)>
(unintern 'myparam)
#'getparam
==> #<FUNCTION GETPARAM NIL ... (BLOCK GETPARAM #:MYPARAM)>
(getparam)
==> 10

请注意,该函数的第二个打印输出包含一个 uninterned 符号。

编辑

如何以任何对它的引用返回上面显示的错误消息的方式删除/取消 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
于 2013-06-20T15:24:18.743 回答
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.
于 2013-06-20T16:31:51.713 回答