在Common Lisp中取消定义类及其所有方法

Mik*_*012 4 common-lisp clos ccl

我想取消定义一个班级及其所有方法,但经过对Googlore的彻底搜索后,我一直无法找到关于如何做到这一点的线索.

我正在使用Commmon Lisp的实现,称为CCL(Clozure CL).

Jos*_*lor 5

这是一个相当有趣的问题.虽然,正如sds的答案所指出的那样,你可以(setf (find-class 'class-name) nil)用来制作(make-instance 'class-name)停止工作的东西,但实际上并没有删除这个类.例如,您可以保存(find-class …)其他地方的早期结果:

CL-USER> (defclass foo () ())
#<STANDARD-CLASS FOO>
CL-USER> (defmethod show ((x foo))
           (print "x is a foo"))
STYLE-WARNING: Implicitly creating new generic function SHOW.
#<STANDARD-METHOD SHOW (FOO) {1002BFD321}>
CL-USER> (defparameter *foo-class* (find-class 'foo))
*FOO-CLASS*
CL-USER> (show (make-instance 'foo))

"x is a foo" 
"x is a foo"
CL-USER> (setf (find-class 'foo) nil)
NIL
CL-USER> (make-instance 'foo)
; Evaluation aborted on #<SIMPLE-ERROR "There is no class named ~ .. {1002FDBC61}>.
CL-USER> (make-instance *foo-class*)
#<#<STANDARD-CLASS FOO> {1003217F91}>
Run Code Online (Sandbox Code Playgroud)

我不确定是否有任何方法可以从系统中删除一个类,并且不清楚它究竟意味着什么,因为它必须解决如何处理类的任何现有实例的问题.

(setf find-class)也不会删除任何专门用于该类的方法.继续刚开始的例子,因为我们仍然可以调用show类的实例,我们仍然可以检索专门的方法:

CL-USER> (show (make-instance *foo-class*))

"x is a foo" 
"x is a foo"
CL-USER> (find-method #'show '() (list *foo-class*))
#<STANDARD-METHOD SHOW ((CLASS #<STANDARD-CLASS FOO>)) {1003A7D081}>
Run Code Online (Sandbox Code Playgroud)

但是,您可以使用REMOVE-METHOD从通用函数中删除适用的方法:

CL-USER> (remove-method #'show (find-method #'show '() (list *foo-class*)))
#<STANDARD-GENERIC-FUNCTION SHOW (0)>
CL-USER> (show (make-instance *foo-class*))
; Evaluation aborted on #<SIMPLE-ERROR "~@<There is no applicable method for the generic function ~2I~_~S~ .. {1002EA5731}>.
Run Code Online (Sandbox Code Playgroud)

在Common Lisp对象系统(CLOS)中,方法不属于类,所以说"[取消定义]类及其所有方法"是没有意义的.相反,CLOS具有泛型函数,程序员定义了专门化泛型函数的方法.如上面的示例所示,虽然可能没有可移植的方法来取消定义类,但您可以删除专门用于该类实例的方法,但您必须追踪它们的内容.有关更多信息,请查看:

comp.lang.lisp上也讨论过这个话题:


sds*_*sds 2

只需使用find-class

(setf (find-class 'myclass) nil)
Run Code Online (Sandbox Code Playgroud)

但是,这不会破坏类对象,也不会删除相应的方法。

完整的过程需要unintern类的符号myclass和槽名称 - 但您可能在其他地方使用这些符号,所以要小心!

您还必须remove-method从您定义的通用函数中获取它们。

总之,这是一个庞大的企业,肯定不值得费力。

只需重新启动 Lisp 会话即可。