关于defparameter
的操作 - 看起来它只会影响参数的符号值单元格:
> (defparameter *p* 16)
*P*
> (symbol-plist '*p*)
NIL
> (setf (symbol-plist '*p*) '(prop1 val1 prop2 val2))
(PROP1 VAL1 PROP2 VAL2)
> (defparameter *p* 16)
*P*
> (symbol-plist '*p*)
(PROP1 VAL1 PROP2 VAL2)
因此plist尚未重置为零。与symbol-function
单元格等相同的操作。这看起来相当尴尬,因为重新加载/编译带有defparameter
的文件会使先前的设置保持不变。有没有方便的方法一次重置所有内容?
答案 0 :(得分:3)
是的,您可以通过unintern
符号完全重置所有内容:
[1]> (defparameter foo 10)
FOO
[2]> (defun foo (x) (1+ x))
FOO
[3]> (setf (get 'foo 'x) 'y)
Y
[4]> (symbol-plist 'foo)
(X Y SYSTEM::DEFINITION
((DEFUN FOO (X) (1+ X)) . #(NIL NIL NIL NIL ((DECLARATION OPTIMIZE DECLARATION)))))
[5]> (setq old-foo 'foo)
FOO
[6]> (unintern 'foo)
T
现在这个符号是未加工的,当我们用read
重新创建它时,它有一个“干净的石板”:
[7]> (fboundp 'foo)
NIL
[8]> (boundp 'foo)
NIL
但我们仍然可以通过old-foo
访问其广告位:
[9]> old-foo
#:FOO
[10]> (fdefinition old-foo)
#<FUNCTION #:FOO (X) (DECLARE (SYSTEM::IN-DEFUN #:FOO)) (BLOCK #:FOO (1+ X))>
PS。正如Barry在评论中提到的那样,这可能会产生意想不到的后果,应谨慎使用。 具体来说,这是一种很好的方法,同时积极开发代码。 但是,在生产中不应该进行这种“清理”操作。
答案 1 :(得分:1)
要添加到sds告诉你的内容,如果你unintern
一个符号并引入一个具有相同名称的新符号,那么你需要重建所有引用未分隔符号的代码,以便它可以引用新的一个。这就是为什么在生产代码中使用是不切实际的,因为重复编译一遍又一遍可能不是一个好主意。
有没有方便的方法一次性重置所有内容?
只需定义一个功能并在适当时重置您需要的内容:
或者,如果您希望在致电defparameter
后仅发生一次,您也可以这样做。
请注意,我建议仅清除您控制的plist的属性,而不是删除其所有内容。环境可能会存储一些有用的东西,比如调试信息。
(defparameter *p* 16)
(eval-when (:compile-time :load-time :execute)
(dolist (property '(prop-a prop-b prop-c))
(setf (get '*p* property) nil)))
编辑:
我忘记了REMF
:
(remf (symbol-plist '*p*) 'property)
上面删除了条目,而(setf (get ...) nil)
将指标绑定到NIL。