【问题标题】:How to get all instances of a class in common lisp?如何在 common lisp 中获取类的所有实例?
【发布时间】:2016-10-03 13:21:46
【问题描述】:

假设我有一堂课:

(defclass person () ())

然后我做了一些实例:

(setf anna (make-instance 'person))    
(setf lisa (make-instance 'person))    

如何获取对象本身或分配给它们的符号名称?

我希望能够说出类似(find-instances 'person) 的内容并获得类似(anna lisa) 或至少(#<PERSON {100700E793}> #<PERSON {100700E793}>) 的内容。

我正在搜索的内容相当于 ruby​​ 中的 each_object

我非常希望能够在没有外部库的情况下做到这一点。

【问题讨论】:

  • 你想在这里达到什么目的?
  • TBH 这更像是一个调试任务,而不是试图实现一些东西。我正在尝试获取 hunchentoot *acceptor* 实例,以便停止正在运行的服务器。但是hunchentoot:*acceptor* 给了我错误,因为我必须在请求的上下文中询问接受者。然而,能够获得一个类的实例似乎很方便,我想我将来也可以使用它,用于调试、检查等......
  • AFAIK,任何解决方案都取决于实现。对于 CCL,请参阅下面的答案。我无法在 SBCL 手册中找到类似的内容,并且谷歌搜索“lispworks heap walk”也没有产生任何结果。
  • @RainerJoswig 这只是一个例子。我编辑了它。

标签: common-lisp clos


【解决方案1】:

Common Lisp 中没有类似的内置功能。

记录实例

为了查找类的所有实例,通常会在实例创建时让类记录实例。可以想象各种机制。有时人们仍然希望实例被垃圾收集 - 然后需要某种非标准的 weak 数据结构来做到这一点。我希望有一些库为 CLOS 实例实现类似的东西。

迭代包的符号

如果您想知道某些或所有包的哪些符号具有 CLOS 实例作为值,您可以遍历它们(DO-SYMBOLSDO-ALL-SYMBOLS、...)并检查是否有符号值和如果该符号值是某个类的实例。

【讨论】:

    【解决方案2】:

    据我所知,没有可移植的解决方案。如果您正在处理CCL,那么map-heap-objects 可能会做,您正在寻找什么

    (defclass foo () ())
    (defvar *x* (make-instance 'foo))
    (defvar *y* (list (make-instance 'foo)))
    
    (defun find-instances (n class)
      (let ((buffer (make-array n :fill-pointer 0 :initial-element nil)))
        (ccl:map-heap-objects (lambda (x)
                                (when (and (typep x class) (< (fill-pointer buffer) n))
                                  (setf (aref buffer (fill-pointer buffer)) x)
                                  (incf (fill-pointer buffer)))))
         buffer))
    
    (find-instances 2 'foo)
    ==> (#<FOO #x30200126F40D> #<FOO #x30200126634D>)
    

    其他 Common Lisp 实现可能存在类似的解决方案。请注意,您必须对遍历可能找到多少个实例有一个初步的预感。原因是(正如 Rainer Joswig 所指出的),回调函数应该避免使用 consing。为了实现这一点,此实现预先分配了一个缓冲区,并最多收集那么多实例。

    【讨论】:

    • 文档说函数应该避免分配内存。因此,使用大量对象导致 GC 可能不是一个好主意...
    • 啊!很好的收获。
    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 2023-03-25
    • 2019-01-29
    • 2017-06-08
    • 2013-08-10
    • 2020-12-18
    • 2023-03-17
    • 2019-01-18
    相关资源
    最近更新 更多