From: Szymon 'tichy'
Subject: object 'finalizer' in SBCL ?
Date: 
Message-ID: <fcmf8d$pm5$1@atlantis.news.tpi.pl>
Hi.

I want class with 'log'.

I mean when an instance of class 'foo' (with
per-instance slot 'id') is GC-ed 'finalizer'
should add that 'id' slot's value to data
structure (for example: to a list) bound to
per-class slot 'log'. Or smthing like that.
Example will be very appreciated :)

TIA.

From: Harald Hanche-Olsen
Subject: Re: object 'finalizer' in SBCL ?
Date: 
Message-ID: <pcozlzluopt.fsf@shuttle.math.ntnu.no>
+ Szymon 'tichy' <········@glombraz.org>:

> I want class with 'log'.
>
> I mean when an instance of class 'foo' (with
> per-instance slot 'id') is GC-ed 'finalizer'
> should add that 'id' slot's value to data
> structure (for example: to a list) bound to
> per-class slot 'log'. Or smthing like that.

Have you looked at section 6.1 in the SBCL manual?

Not that I think what you ask is a very good idea, due to the
unpredictable nature of when objects are collected.  You are probably
better off keeping track of when objects are no longer needed, then
logging the fact and invalidating them somehow so further attempts at
using them signals an error.  (Probably, you're really better off
doing nothing of the sort.  It all depends on what problem you're
really trying to solve.)

Oh, and notice that section 6.1 in the manual is part of chapter 6,
entitled "Beyond the ANSI Standard".  Which ought to indicate that
there is no portable way to do what you ask, if that bothers you.
Maybe it should.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
  when there is no ground whatsoever for supposing it is true.
  -- Bertrand Russell
From: Szymon 'tichy'
Subject: Re: object 'finalizer' in SBCL ?
Date: 
Message-ID: <fcmkq1$flm$1@atlantis.news.tpi.pl>
Harald Hanche-Olsen wrote:
> + Szymon 'tichy' <········@glombraz.org>:
> 
>> I want class with 'log'.
>>
>> I mean when an instance of class 'foo' (with
>> per-instance slot 'id') is GC-ed 'finalizer'
>> should add that 'id' slot's value to data
>> structure (for example: to a list) bound to
>> per-class slot 'log'. Or smthing like that.
> 
> Have you looked at section 6.1 in the SBCL manual?

Yes. But... there was something wrong with output,
so my example failed. I gave it second try,
and it worked :)

CL-USER> (defclass test () ())
#<STANDARD-CLASS TEST>

CL-USER> (defparameter *test* (make-instance 'test))
*TEST*

CL-USER> (gc :full t) ; no thing should happen
NIL

CL-USER> (prog1 :please-work
            (sb-ext:finalize *test* (lambda () (princ "more or less... it works."))))
:PLEASE-WORK

CL-USER> (gc :full t) ; no thing should happen
NIL

CL-USER> (setq *test* '|Sooner or later, everyone is going to die.|)
|Sooner or later, everyone is going to die.|

CL-USER> (gc :full t)
more or less... it works.
NIL

> [...] (Probably, you're really better off
> doing nothing of the sort.  It all depends on what problem you're
> really trying to solve.)

I have two ideas. One is evil. Second idea is to use finalizer
to test (2 logs, one will use finalizer, if they are going to
be equal then (probably) everything should be ok).

Regards, Szymon.
From: Szymon 'tichy'
Subject: Re: object 'finalizer' in SBCL ?
Date: 
Message-ID: <fcmrb0$8vg$1@atlantis.news.tpi.pl>
Szymon 'tichy' wrote:
> Hi.
> 
> I want class with 'log'.

> [...]

> Example will be very appreciated :)

;; seems to work:

CL-USER> (progn
            (defvar *test*)
            (defvar *syms*)

            (setq *syms* '(first 2 3 4 5 6 7 8 9 last))

            (defun make-garbage ()
              (loop repeat 10000 collect (gensym)))

            (defclass test ()
              ((id :initarg :id)
               (log :allocation :class :initform (list '()))))

            (defmethod initialize-instance :after ((obj test) &key)
              (let ((id (slot-value obj 'id))
                    (log (slot-value obj 'log)))
                (sb-ext:finalize obj (lambda () (push id (car log))))))

            (defmethod print-object ((obj test) stream)
              (print-unreadable-object (obj stream :type t :identity t)
                (format stream
                        "ID ~S, LOG ~S"
                        (slot-value obj 'id)
                        (slot-value obj 'log))))

            (dolist (sym *syms*) (setq *test* (make-instance 'test :id sym))))
NIL

CL-USER> *test*
#<TEST ID LAST, LOG (NIL) {B3AA3E9}>

CL-USER> (loop repeat 10 do (make-garbage) (gc :full t))
NIL

CL-USER> *test*
#<TEST ID LAST, LOG ((9 8 7 6 5 4 3 2 FIRST)) {A7BF2B1}>

Regards, Szymon.