I would like to undefine a class and all of its methods but after a quite thorough search on Googlore I have been unable to find a clue about how to do this.
I am using an implementation of Commmon Lisp called CCL (Clozure CL).
I would like to undefine a class and all of its methods but after a quite thorough search on Googlore I have been unable to find a clue about how to do this.
I am using an implementation of Commmon Lisp called CCL (Clozure CL).
这是一个相当有趣的问题。虽然,正如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}>
我不确定实际上是否有任何方法可以从系统中删除一个类,也不清楚这样做到底意味着什么,因为它必须解决如何处理该类的任何现有实例的问题.
(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}>
但是,您可以使用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}>.
在 Common Lisp 对象系统 (CLOS) 中,方法不属于类,因此说“[取消定义] 一个类及其所有方法”是没有意义的。相反,CLOS 具有泛型函数,并且程序员定义了专门化泛型函数的方法。如上面的示例所示,虽然可能没有可移植的方式来取消定义类,但您可以删除专门用于该类实例的方法,但您必须追踪它们是什么。有关更多信息,请查看:
这个话题也在 comp.lang.lisp 上讨论过:
只需使用find-class
:
(setf (find-class 'myclass) nil)
但是,这不会破坏类对象,也不会删除相应的方法。
整个过程需要取消实习myclass
符号和类的插槽名称 - 但您可能在其他地方使用这些符号,所以要小心!
您还必须remove-method
从定义它们的通用函数中获取。
总之,这是一个巨大的企业,肯定不值得努力。
只需重新启动您的 Lisp 会话。
这不是可移植的,但在像 LispWorks 这样的 IDE 中:
使用类浏览器,列出没有继承的类的所有方法,选择方法,从方法菜单调用undefine
在编辑器中选择defclass
表单,在定义菜单中调用undefine
CCL IDE 可能没有这些命令,但SLIME + Emacs可能有类似的东西。
我只是偶然发现了这个:
HyperSpec 中的标准泛型函数#'make-instances-obsolete
。特别注意它#'defclass
在重新定义“标准类”时如何交互。
另请查看#'fmakunbound
、#'unintern
和#'delete-package
(remove-method
(find-method #'<generic-function-symbol>
'(:before :after :<some-other-qualifier-you-may-be-interested-in>)
;; specializers are the classes or eq specializers
;; in method lambda lists
'(<first-specializer> <second-specializer-and-so-on>)))
最后一段代码接近Joshua Taylor 的答案。