common-lisp - 如何更改类的元类

标签 common-lisp sbcl clos

这种情况一次又一次地发生在我身上:我定义了类,却忘记了我希望它是可调用的,或者它是 Gtk 小部件类,因此需要说明它的元类。但是,一旦定义了它,SBCL 就不允许我更改元类(即使没有此类的实例)。例如,评估

(defclass foo ()
  ((slot-a)))

然后添加一个元类并重新评估:
(defclass foo ()
  ((slot-a))
  (:metaclass gobject:gobject-class))

导致错误:
Cannot CHANGE-CLASS objects into CLASS metaobjects.
   [Condition of type SB-PCL::METAOBJECT-INITIALIZATION-VIOLATION]
See also:
  The Art of the Metaobject Protocol, CLASS [:initialization]

不幸的是,我没有《元对象协议(protocol)的艺术》的副本来检查它的内容。目前我能想到的唯一方法是重新启动 lisp,这可能会造成很大的破坏。

由于我很快意识到错误,我不介意通过删除它来完全避开定义的类。问题:
  • 如果我创建了该类的实例,有没有办法找到它们以使它们无效并让它们被 GCed?
  • 如何删除类?像 fmakunbound对于功能。
  • 最佳答案

    Unfortunately I don't have a copy of The Art of the Metaobject Protocol to check what it says.



    即使我推荐阅读这本书,你也可以在网上找到一些信息。参见示例 ENSURE-CLASS-USING-CLASS .

    How to remove the class?



    您可以使用 (SETF FIND-CLASS) :
    (setf (find-class 'foo) nil)
    

    或者,您可以使用花哨的粘液检查器。您调用slime-inspect-defintion同时指向类的名称。然后,您将看到名称。当你选择它时,你检查命名你的类的符号。然后,您可以看到如下内容:
    It names the class FOO [remove]
    

    如果 FOO 只命名一个类,您可以使用更大的锤子:
    (unintern 'foo)
    

    If I have created instances of the class, is there a way to find them to nullify them and get them GCed?



    不,只有 GC 具有全局 View ,并且出于实际原因,它通常不会保留关于谁引用特定对象(以及如何引用)的向后引用 1 .
    除非您引入自己的(弱)哈希表来存储它们,否则没有类的所有实例的全局记录。但是,如果您保留了所有实例的记录,则可以 CHANGE-CLASS 他们。例如,您定义:
    (defclass garbage () ())
    

    ...您的对象中任何先前持有的引用都将被释放,并且 GC 有机会处理您的实例引用的对象。并且当另一个对象引用 'garbage 的实例时,您可以对其进行更新。您可以将旧类的实例更改为新类,而不是使用 'garbage(名称相同,但类对象不同)。
    另请注意 CHANGE-CLASS是一个通用函数。

    1 .实现可能会提供堆遍历器。参见示例 Heap walkers in Allegro CL .

    关于common-lisp - 如何更改类的元类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38811931/

    相关文章:

    vector - 如何将数字向量转换为整数?

    methods - 普通 lisp 中的匿名方法

    mysql - SBCL 中的 clsql 问题

    input - 将输入字符串分配并打印到变量。口齿不清

    common-lisp - 从 Common Lisp/SBCL 中获得更高的速度

    common-lisp - CLOS:我在这里做什么,在元类中设置一个槽?

    inheritance - 相当于 CLOS 的 instanceof?如何检查实例是否从另一个对象继承?

    compiler-errors - SBCL 错误消息 : Any way to improve?

    keyboard - common lisp,如何屏蔽键盘输入

    common-lisp - cl-pdf bar-codes.lisp 中的条形码无效?