Common lisp 反参数操作

Common lisp 反参数操作,common-lisp,Common Lisp,关于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 PR

关于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函数单元格等类似的操作。这似乎相当尴尬,因为使用defparameters重新加载/编译文件时会保留先前的设置。是否有任何方便的方法可以立即重置所有内容?

是的,您可以通过单击符号完全重置所有内容:

[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访问其插槽:

注:正如巴里在评论中提到的,这可能会产生意想不到的后果,应谨慎使用。 具体来说,这是一种很好的方法,同时可以积极开发代码。
但是,在生产中不需要进行此清理操作。

是的,您可以通过取消符号完全重置所有内容:

[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访问其插槽:

注:正如巴里在评论中提到的,这可能会产生意想不到的后果,应谨慎使用。 具体来说,这是一种很好的方法,同时可以积极开发代码。
但是,在生产中应该不需要进行这种清理操作。

要补充sds告诉您的内容,如果您取消了一个符号并引入了一个同名的新符号,那么您需要重新生成引用该未经处理符号的所有代码,以便它可以引用新符号。这就是为什么在生产代码中使用它是不切实际的,在生产代码中反复编译可能不是一个好主意

有什么方便的方法可以立即重置所有内容吗

只需定义一个函数,并在适当时重置所需的内容: 或者,如果希望在调用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)))
编辑:

我忘了:


上面删除了条目,而setf get。。。nil将指示符绑定到nil。

要添加到sds告诉您的内容中,如果您取消插入符号并引入具有相同名称的新符号,则需要重新生成引用未插入符号的所有代码,以便它可以引用新符号。这就是为什么在生产代码中使用它是不切实际的,在生产代码中反复编译可能不是一个好主意

有什么方便的方法可以立即重置所有内容吗

只需定义一个函数,并在适当时重置所需的内容: 或者,如果希望在调用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)))
编辑:

我忘了:


上面删除了条目,而setf get。。。nil将指示符绑定到nil。

DEFPARAMETER仅对变量进行操作。属性列表与其作为变量的使用完全无关。DEFPARAMETER仅对变量进行操作。属性列表与其作为变量的使用完全无关。这将执行所需的重置,但可能有其他含义。如果在同一源文件中有对符号的引用,则在您取消插入后,它们可能找不到替换符号。因此,如果我理解正确,我应该将取消插入的“foo”放在def参数“foo”之前。。。在源文件中;然后将两者都包装在一个eval中,以确保在重新编译时不会拾取旧单元格?不,请阅读PS。您应该在开发时在提示下执行此操作。这在生产代码中没有位置。我认为在生产中设置为零比取消它们更安全?@MadPhysicast:如果你对生产有这样的问题,你需要重新考虑你的设计。这将实现所需的重置,但可能有其他影响。如果在同一源文件中有对符号的引用,则在您取消插入后,它们可能找不到替换符号。因此,如果我理解正确,我应该将取消插入的“foo”放在def参数“foo”之前。。。在源文件中;然后将两者都包装在一个eval中,以确保在重新编译时不会拾取旧单元格?不,请阅读PS。您应该在开发时在提示下执行此操作。这在生产代码中没有位置。我认为在生产中设置为零比取消它们更安全?@MadPhysical:如果你对生产有这样的问题,你需要重新考虑你的设计。