From: Warren Lynn on
Hi,

I wish to control when finalize-inheritance is called for my own
metaclass instances (class metaobjects). More specifically, I want to
ensure finalize-inheritance won't be called until the first instance
is going to be allocated. That is, I want to delay finalize-
inheritance to the last minute (because my class metaobject has
dependency on other things in addition to the definition of all its
superclasses).

I could not find out how to do it. But the following excerpt of the
"Class Finalization Protocol" seems to hint that is possible, as it
says "... depends on the class of the class metaobject"

"The exact point at which finalize-inheritance is called depends on
the class of the class metaobject; for standard-class it is called
sometime after all the classes superclasses are defined, but no later
than when the first instance of the class is allocated (by allocate-
instance)."

Can anyone give me some idea how this can be done? Thanks a lot.


From: Pascal Costanza on
On 22/07/2010 03:57, Warren Lynn wrote:
> Hi,
>
> I wish to control when finalize-inheritance is called for my own
> metaclass instances (class metaobjects). More specifically, I want to
> ensure finalize-inheritance won't be called until the first instance
> is going to be allocated. That is, I want to delay finalize-
> inheritance to the last minute (because my class metaobject has
> dependency on other things in addition to the definition of all its
> superclasses).
>
> I could not find out how to do it. But the following excerpt of the
> "Class Finalization Protocol" seems to hint that is possible, as it
> says "... depends on the class of the class metaobject"
>
> "The exact point at which finalize-inheritance is called depends on
> the class of the class metaobject; for standard-class it is called
> sometime after all the classes superclasses are defined, but no later
> than when the first instance of the class is allocated (by allocate-
> instance)."
>
> Can anyone give me some idea how this can be done? Thanks a lot.

Off the top of my head, without testing this at all:

(defclass my-class (standard-class)
((finalizer :accessor finalizer :initform (lambda ()))))

(defmethod finalize-inheritance ((class my-class))
(setf (finalizer class) #'call-next-method))

(defmethod allocate-instance :before ((class my-class) &rest initargs)
(declare (ignore initargs))
(funcall (finalizer class))
(setf (finalizer class) (lambda ())))

....but maybe it's also good to know what your use case is: What do you
actually want to achieve? Maybe there is a better solution...


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Warren Lynn on
On Jul 22, 5:56 am, Pascal Costanza <p...(a)p-cos.net> wrote:
> On 22/07/2010 03:57, Warren Lynn wrote:
>
>
>
>
>
> > Hi,
>
> > I wish to control when finalize-inheritance is called for my own
> > metaclass instances (class metaobjects). More specifically, I want to
> > ensure finalize-inheritance won't be called until the first instance
> > is going to be allocated. That is, I want to delay finalize-
> > inheritance to the last minute (because my class metaobject has
> > dependency on other things in addition to the definition of all its
> > superclasses).
>
> > I could not find out how to do it. But the following excerpt of the
> > "Class Finalization Protocol" seems to hint that is possible, as it
> > says "... depends on the class of the class metaobject"
>
> > "The exact point at which finalize-inheritance is called depends on
> > the class of the class metaobject; for standard-class it is called
> > sometime after all the classes superclasses are defined, but no later
> > than when the first instance of the class is allocated (by allocate-
> > instance)."
>
> > Can anyone give me some idea how this can be done? Thanks a lot.
>
> Off the top of my head, without testing this at all:
>
> (defclass my-class (standard-class)
>    ((finalizer :accessor finalizer :initform (lambda ()))))
>
> (defmethod finalize-inheritance ((class my-class))
>    (setf (finalizer class) #'call-next-method))
>
> (defmethod allocate-instance :before ((class my-class) &rest initargs)
>    (declare (ignore initargs))
>    (funcall (finalizer class))
>    (setf (finalizer class) (lambda ())))
>
> ...but maybe it's also good to know what your use case is: What do you
> actually want to achieve? Maybe there is a better solution...
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/- Hide quoted text -
>
> - Show quoted text -

This is a indeed a very neat trick. I was concerned that this trick
will not work with inheritance, but actually it seems to work fine in
my test. It seems it is not a requirement that all superclasses have
to be finalized before a subclass can be finalized.

My use case is: I am trying to write a metaclass on top of the "dao"
metaclass in postmodern for managing the relationships between
persistent objects. So the persistent classes will have dependencies
among them (caused by many2one, one2one, many2many relationships) and
some information needs to be computed after all those persistent
classes have been defined. If I can ensure the finalize method won't
be called before I make any instances, then I can be sure all classes
are defined when a finalize method is called, as I won't make any
instances until all the class definitions are loaded. I can add a
function like "finalize-all-my-classes" and call it after all my
classes are defined, but that seems clumsy to me.