<nikodemus@random-state.net> wrote:
+---------------
| Also, some implementations provide finalizers...
...
| [ Note: make sure your finalizer doesn't retain any references to the
| object being finalized: then it'll never be GC'd. ]
+---------------
And in practice, this almost always means that you need another level
of indirection: the finalized object has to contain a pointer to the
"real" object you're worrying about, which the finalizer also contains
a pointer to (or is closed over, same thing). To extend your example:
> (defmethod make-cleanup-thunk ((thing string))
(lambda ()
(format t "The ~s has been cleaned up!~%" thing)))
#<Standard-Method MAKE-CLEANUP-THUNK (STRING) {484C68A5}>
> (let* ((x "Thing needing cleaning")
(y (list x)))
(finalize y (make-cleanup-thunk x))
'done)
DONE
> (gc)
NIL
> (gc)
The "Thing needing cleaning" has been cleaned up!
NIL
>
[Note that it took two calls to GC in this case -- for no special
reason, just that the first one only needed to do a minor GC and
thus the finalized cons cell didn't get freed during the first one.]
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607