From: Roos Van Raadshooven L.A. (Leon)
Subject: adding code to make-instance
Date:
Message-ID: <roosvanr.903483138@biceps>
Hi all,
I hope this question is not too FAQqy, but I'll ask it anyway.
I'm trying to add some code to be executed with every make-instance of some
class. I managed to do that for class1 in the code below, but it does not
work for calls to make-instance of classes derived from that class. I would
like to be able to do that too. So, in the code below, I would like the
the code in the :around method to be called for (make-instance 'class2).
The code:
(defclass class1 ()
((slot1
:initform nil
:initarg :slot1
:accessor get-slot1)))
(defmethod method1 ((this class1) &rest initargs)
(list (get-slot1 this) initargs))
(defmethod make-instance :around ((cls (eql 'class1)) &rest options)
(declare (ignore options))
(let ((obj (call-next-method)))
(format t "The created object-instance: ~s~%" obj)
(force-output)
obj))
(defclass class2 (class1) ())
;;---
Top level:
user(7): (setq qqqq (make-instance 'class1))
The created object-instance: #<class1 @ #x204f2d22>
#<class1 @ #x204f2d22>
user(8): (setq qqqq (make-instance 'class2))
#<class2 @ #x204f2eca>
I also tried replacing (eql 'class1) by (eql (find-class 'class1))
in the :around method, but that didn't work.
Thanks for your help,
Leon.
In article <··················@biceps>,
Roos Van Raadshooven L.A. (Leon) <········@storm.research.kpn.com> wrote:
>
>I hope this question is not too FAQqy, but I'll ask it anyway.
>
>I'm trying to add some code to be executed with every make-instance of some
>class.
I'm not sure that is the approach to take....
>(defmethod make-instance :around ((cls (eql 'class1)) &rest options)
This method is defined on the singleton composed on CLASS1. The
class itself is an object. That object is an instance of a class
object, just like CLASS2. However, the object that signifies
class2 isn't a subclass of CLASS1. Both are instances of the same
class (objects which represent classes ).
Therefore, (make-instance 'class2 ) won't invoke the above method because
the argument CLASS2 doesn't make it applicable. The class CLASS1 is
the sole object is that is applicable to the above method. In essence.
(defmethod foo ((obj (eql 1 )) ) ... )
If you pass 2, it isn't a match.
What I think you wish to do is modify the initialization process.
To do something to instances of CLASS1 at the time they are created.
There are a other generic functions can take additions to do this, not
MAKE-INSTANCE. Namely, INITIALIZE-INSTANCE or perhaps SHARED-INITIALIZE.
;; presuming you don't wish to get a hold of any of the initiarg keywords
;; the following ignores them...
(defmethod initialize-instance :after ( (obj class1 ) &key )
(format t "The created object-instance: ~s ~%" ojb )
(force-output )
obj)
This method is specialized on instances of CLASS1. Since instances of
CLASS2 are also instances of CLASS1, this method is also applicable to
them. This method also presumes that you can "do" what ever you want
done after the object has been initialized, but before its value is
made generally available.
CL-USER 1 > (setq some-class1 (make-instance 'class1 ))
The created object-instance: #<CLASS1 20F0C864>
#<CLASS1 20F0C864>
CL-USER 2 > (setq some-class2 (make-instance 'class2))
The created object-instance: #<CLASS2 20F6BCC4>
#<CLASS2 20F6BCC4>
--
Lyman S. Taylor "Because no matter where you go,
(·····@cc.gatech.edu) there you are."
Buckaroo Banzai
In article <··················@biceps>,
Roos Van Raadshooven L.A. (Leon) <········@storm.research.kpn.com> wrote:
>I'm trying to add some code to be executed with every make-instance of some
>class. I managed to do that for class1 in the code below, but it does not
>work for calls to make-instance of classes derived from that class. I would
>like to be able to do that too. So, in the code below, I would like the
>the code in the :around method to be called for (make-instance 'class2).
You need to define your method on a generic function that takes an
instance, not the class itself, so that inheritance will take place. The
generic function INITIALIZE-INSTANCE is the function that works this way.
(defmethod initialize-instance :around ((self class1) &rest options)
(declare (ignore options))
(call-next-method)
(format t "The created object-instance: ~S~%" self)
(force-output)
self)
--
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.