Hi,
I'll apologize for the stupid example in advance.
Suppose I have two CLOS classes, e.g.:
(defclass foo () ())
(defclass bar (foo) ())
and I now want to modify their respective object initialization.
Now, say I want to or do something with the returned instances:
(defmethod make-instance :around ((class (eql (find-class 'foo)))
&rest initargs &key &allow-other-keys)
(let ((instance (call-next-method)))
(format t "New foo instance")
(do-something-with instance)
instance))
(defmethod make-instance :around ((class (eql (find-class 'bar)))
&rest initargs &key &allow-other-keys)
(let ((instance (call-next-method)))
(format t "New bar instance")
(do-something-else-with instance)
instance))
Now, this won't work out as expected because the around method for foo
will never get called:
CL-USER>(make-instance 'bar)
New bar instance
#<BAR {A8A8739}>
Now, I believe I understand why this happens (the primary method for
make-instance 'bar is more specific than any primary or auxillary
method on 'foo and of course that default method for (make-instance
'bar) doesn't know it should call call-next-method again), but what I
don't know is how to achieve what I want: That the around method on
the super-class will be called.
I expect the answer is the MOP? Or is there some other way?
Holger
--
--- http://hillview.bugwriter.net/ ---
Fachbegriffe der Informatik - Einfach erkl�rt
4: Garbage Collection
Windows 95 (Kristian K�hntopp)
Hello,
> (defclass foo () ())
> (defclass bar (foo) ())
>
> and I now want to modify their respective object initialization.
> Now, say I want to or do something with the returned instances:
>
> (defmethod make-instance :around ((class (eql (find-class 'foo)))
> &rest initargs &key &allow-other-keys)
> (let ((instance (call-next-method)))
> (format t "New foo instance")
> (do-something-with instance)
> instance))
>
> (defmethod make-instance :around ((class (eql (find-class 'bar)))
> &rest initargs &key &allow-other-keys)
> (let ((instance (call-next-method)))
> (format t "New bar instance")
> (do-something-else-with instance)
> instance))
>
> Now, this won't work out as expected because the around method for foo
> will never get called:
The specializer (EQL (FIND-CLASS 'FOO)) means that the method is
called if its argument is /exactly/ the #<CLASS FOO>, and not some
other object, including a subclass of FOO. What you need is to define
a method for an initialization generic function - in your case it is
INITIALIZE-INSTANCE. See http://www.lispworks.com/documentation/HyperSpec/Body/f_init_i.htm
and http://www.lispworks.com/documentation/HyperSpec/Body/07_a.htm.
On 4964 September 1993, ········@tochka.ru wrote:
>> Now, this won't work out as expected because the around method for foo
>> will never get called:
> The specializer (EQL (FIND-CLASS 'FOO)) means that the method is
> called if its argument is /exactly/ the #<CLASS FOO>, and not some
> other object, including a subclass of FOO.
*Whack* (smashing head on table). Of course.
I shouldn't post at 2am. Nor code, I guess.
Thanks a lot,
Holger
--
--- http://hillview.bugwriter.net/ ---
Fachbegriffe der Informatik - Einfach erkl�rt
58: Shareware installieren
Die System Clock um drei Monate zur�ckstellen (Peter Berlich)
On Apr 4, 4:48 pm, Holger Schauer <··············@gmx.de> wrote:
> Hi,
>
> I'll apologize for the stupid example in advance.
> Suppose I have two CLOS classes, e.g.:
>
> (defclass foo () ())
> (defclass bar (foo) ())
>
> and I now want to modify their respective object initialization.
> Now, say I want to or do something with the returned instances:
>
> (defmethod make-instance :around ((class (eql (find-class 'foo)))
> &rest initargs &key &allow-other-keys)
> (let ((instance (call-next-method)))
> (format t "New foo instance")
> (do-something-with instance)
> instance))
>
> (defmethod make-instance :around ((class (eql (find-class 'bar)))
> &rest initargs &key &allow-other-keys)
> (let ((instance (call-next-method)))
> (format t "New bar instance")
> (do-something-else-with instance)
> instance))
You probably want to add methods to SHARED-INITIALIZE rather than
MAKE-INSTANCE.
Joe Marshall wrote:
> On Apr 4, 4:48 pm, Holger Schauer <··············@gmx.de> wrote:
>
>>Hi,
>>
>>I'll apologize for the stupid example in advance.
>>Suppose I have two CLOS classes, e.g.:
>>
>>(defclass foo () ())
>>(defclass bar (foo) ())
>>
>>and I now want to modify their respective object initialization.
>>Now, say I want to or do something with the returned instances:
>>
>>(defmethod make-instance :around ((class (eql (find-class 'foo)))
>> &rest initargs &key &allow-other-keys)
>> (let ((instance (call-next-method)))
>> (format t "New foo instance")
>> (do-something-with instance)
>> instance))
>>
>>(defmethod make-instance :around ((class (eql (find-class 'bar)))
>> &rest initargs &key &allow-other-keys)
>> (let ((instance (call-next-method)))
>> (format t "New bar instance")
>> (do-something-else-with instance)
>> instance))
>
>
> You probably want to add methods to SHARED-INITIALIZE rather than
> MAKE-INSTANCE.
>
Note to OQ: I think most folks use initialize-instance :after.
Shared-init may be more appropriate, depending on what you are doing --
it runs also on rarer occasions such as reinitialize-instance.
kt
--
"As long as algebra is taught in school,
there will be prayer in school." - Cokie Roberts
"Stand firm in your refusal to remain conscious during algebra."
- Fran Lebowitz
"I'm an algebra liar. I figure two good lies make a positive."
- Tim Allen
"Algebra is the metaphysics of arithmetic." - John Ray
http://www.theoryyalgebra.com/