Google Groupes n'accepte plus les nouveaux posts ni abonnements Usenet. Les contenus de l'historique resteront visibles.

Querying Class object to get instances

11 vues
Accéder directement au premier message non lu

Frederick C. Gibson, Architect

non lue,
12 juin 1999, 03:00:0012/06/1999
à
Is there a way in CLOS to get a list of all instances from the class object
of which the instances are members?

Thanks!

Fred Gibson, Architect

Fred...@gibson-design.com Architecture Designed Objectively
==================================-----------||||||||||||||||||||||
Frederick Clifford Gibson Architect & Associates

1220 14th Avenue Suite 106
San Francisco, CA 94122
415.753.3797 |tel| 415.759.8848 |fax|

(c)1999 http://www.gibson-design.com

EASG: Epistemology-Aesthetics Study Group
http://www.gibson-design.com/philosophy
ART: American Renaissance for the Twenty-First Century
http://www.art-21.org

Kent M Pitman

non lue,
12 juin 1999, 03:00:0012/06/1999
à
"Frederick C. Gibson, Architect" <Fred...@gibson-design.com> writes:

> Is there a way in CLOS to get a list of all instances from the class object
> of which the instances are members?

Not by default. You can, in an implementation that supports a MOP,
use a user-defined metaclass that upon instantiation logs the instances.

You can also, on a special-case basis for a specific class, do this
without metaclasses by just adding an after method on INITIALIZE-INSTANCE
for the class that pushes the element onto some list.

(defvar *the-foos* '())

(defmethod initialize-instance :after ((self foo) &key)
(push self *the-foos*))

There is a problem with doing it that way (which is why metclasses are
a better way) because if you subclass FOO you won't get a new
variable. You might think you could solve this by doing:

(defclass foo ()
((all-instances :allocation :class :accessor all-instances :initform '())))

and then pushing onto (all-instances self), which would be the class
slot. But the problem is that you'll get the same bug because when you
subclass a class with a slot that uses :allocation :class, you do not
get a new slot for each subclass--the subclasses all share the same
slot. [The Dylan lanuage has something that would in CL be called
:allocation :each-subclass, which is what you really want and CL does
not provide.]

SOMETIMES having the shared variable is actually right, but often it is not
so you have to think about it in advance.

I have sometimes worked around this by doing

(defvar *all-instances* nil)

(defmethod initialize-instance :after ((self instance-recording-class) &key)
(push self (getf *all-instances* (class-of self))))

(defmethod all-instances ((self instance-recording-class))
(getf *all-instances* (class-of self)))

or something like that. I think if you search in Deja News, or maybe
even look in the FAQ, you can probably find one or more worked examples
of doing something like this with the MOP stuff, that I'm not super-familiar
with mostly because I've always preferred to write really portable code
that doesn't require the MOP.

Incidentally, whether you use the MOP or not, there is an issue that you
can end up really defeating garbage collection if you keep track of all
the instances, so be very careful with anything like this and use it only
if you really have to. I think some implementations may have tools that
sweep the address space looking for instances exactly to avoid the gc locking
problem, but that's not a basic CL operation, and implementations are not
required to include enough information in the image to actually be able to
recover such... (Such tools would necessarily cons, though, upon
demand, and so you'd risk holding a pointer to things that want to GC even
if you use one of them. )

You could also use weak hash tables (which most implementations provide
but are not standard) to help avoid the gc locking problem for instances.

Erik Naggum

non lue,
20 juin 1999, 03:00:0020/06/1999
à
* "Frederick C. Gibson, Architect" <Fred...@gibson-design.com>

| Is there a way in CLOS to get a list of all instances from the class object
| of which the instances are members?

no, but some Common Lisp implementations provide access to heap walkers
from their memory management subsystems that return a list of all "live"
objects of a particular system type. STANDARD-INSTANCE is typically such
a system type, but you can easily test for the correct classness
yourself. which Common Lisp are you using?

#:Erik
--
@1999-07-22T00:37:33Z -- pi billion seconds since the turn of the century

0 nouveau message