From: Holger Schauer
Subject: Customizing object initialisation
Date: 
Message-ID: <yxzvegbitvf.fsf@elendil.holgi.priv>
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)

From: ········@tochka.ru
Subject: Re: Customizing object initialisation
Date: 
Message-ID: <1175739971.741941.295600@n76g2000hsh.googlegroups.com>
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.
From: Holger Schauer
Subject: Re: Customizing object initialisation
Date: 
Message-ID: <yxzodm3s43s.fsf@gmx.de>
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)
From: Joe Marshall
Subject: Re: Customizing object initialisation
Date: 
Message-ID: <1175791098.505324.140390@n76g2000hsh.googlegroups.com>
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.
From: Ken Tilton
Subject: Re: Customizing object initialisation
Date: 
Message-ID: <e0jRh.239$hU4.97@newsfe12.lga>
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/