From: ···········@technovolve.co.za
Subject: initialize-instance :after
Date: 
Message-ID: <1183397721.916951.56480@o61g2000hsh.googlegroups.com>
Hi, I am a CL newbie.  I hope someone can give me some advice.  Given
the following code snippet:

(defclass foo-base () ())

(defmethod initialize-instance :after ((self foo-base) &key text)
  (format t "~a~%" text))

(defclass foo-child (foo-base) ())

When executing:

(make-instance 'foo-base :text "foo-base")
=> foo-base is printed

(make-instance 'foo-child :text "foo-child")
=> foo-child is printed

My question is is there a way (define a method :before, :after, etc.)
to change the binding of text that is supplied to initialize-
instance :after spesialized on foo-base when called indirectly when an
instance of foo-child is created (by make-instance 'foo-child).  I
tried to create a initialize-instance specialized on foo-child and
call call-next-method with a changed value for text, but the change is
not called through to the :after method.

So what I am trying to do is basically insert a method in between, to
change the value of text before initialize-instance :after specialized
on foo-base is called, when a instance of foo-child is created.

Thank you for any help.

Leon

From: Pascal Costanza
Subject: Re: initialize-instance :after
Date: 
Message-ID: <5ess6dF38oa7rU2@mid.individual.net>
···········@technovolve.co.za wrote:
> Hi, I am a CL newbie.  I hope someone can give me some advice.  Given
> the following code snippet:
> 
> (defclass foo-base () ())
> 
> (defmethod initialize-instance :after ((self foo-base) &key text)
>   (format t "~a~%" text))
> 
> (defclass foo-child (foo-base) ())
> 
> When executing:
> 
> (make-instance 'foo-base :text "foo-base")
> => foo-base is printed
> 
> (make-instance 'foo-child :text "foo-child")
> => foo-child is printed
> 
> My question is is there a way (define a method :before, :after, etc.)
> to change the binding of text that is supplied to initialize-
> instance :after spesialized on foo-base when called indirectly when an
> instance of foo-child is created (by make-instance 'foo-child).  I
> tried to create a initialize-instance specialized on foo-child and
> call call-next-method with a changed value for text, but the change is
> not called through to the :after method.

Indeed, this doesn't work if you do this in a primary method. Try using 
an :around method instead.


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: ···········@technovolve.co.za
Subject: Re: initialize-instance :after
Date: 
Message-ID: <1183399131.341687.101490@o61g2000hsh.googlegroups.com>
Hi Pascal

Thank you very much, I tried a :around method and it works perfectly.

Regards,

Leon
From: Pascal Bourguignon
Subject: Re: initialize-instance :after
Date: 
Message-ID: <87lkdyllhe.fsf@informatimago.com>
···········@technovolve.co.za writes:

> Hi, I am a CL newbie.  I hope someone can give me some advice.  Given
> the following code snippet:
>
> (defclass foo-base () ())
>
> (defmethod initialize-instance :after ((self foo-base) &key text)
>   (format t "~a~%" text))
>
> (defclass foo-child (foo-base) ())
>
> When executing:
>
> (make-instance 'foo-base :text "foo-base")
> => foo-base is printed
>
> (make-instance 'foo-child :text "foo-child")
> => foo-child is printed
>
> My question is is there a way (define a method :before, :after, etc.)
> to change the binding of text that is supplied to initialize-
> instance :after spesialized on foo-base when called indirectly when an
> instance of foo-child is created (by make-instance 'foo-child).  I
> tried to create a initialize-instance specialized on foo-child and
> call call-next-method with a changed value for text, but the change is
> not called through to the :after method.
>
> So what I am trying to do is basically insert a method in between, to
> change the value of text before initialize-instance :after specialized
> on foo-base is called, when a instance of foo-child is created.
>
> Thank you for any help.

Where?


(defclass base ()
  ())

(defclass spec (base)
  ())


(defmethod m ((self base))
  (print `(m base ,self)))

(defmethod m :before ((self base))
  (print `(m :before base ,self)))

(defmethod m :around ((self base))
  (print `(m :around (before) base ,self))
  (multiple-value-prog1 (call-next-method)
    (print `(m :around (after) base ,self))))

(defmethod m :after ((self base))
  (print `(m :after base ,self)))


(defmethod m ((self spec))
  (print `(m spec (before) ,self))
  (multiple-value-prog1 (call-next-method)
    (print `(m spec (after) ,self))))

(defmethod m :before ((self spec))
  (print `(m :before spec ,self)))

(defmethod m :around ((self spec))
  (print `(m :around (before) spec ,self))
  (multiple-value-prog1 (call-next-method)
    (print `(m :around (after) spec ,self))))

(defmethod m :after ((self spec))
  (print `(m :after spec ,self)))


(m (make-instance 'base))

(M :AROUND (BEFORE) BASE #<BASE #x207CBA6E>) 
(M :BEFORE BASE #<BASE #x207CBA6E>) 
(M BASE #<BASE #x207CBA6E>) 
(M :AFTER BASE #<BASE #x207CBA6E>) 
(M :AROUND (AFTER) BASE #<BASE #x207CBA6E>) 
(M BASE #<BASE #x207CBA6E>)



(m (make-instance 'spec))

(M :AROUND (BEFORE) SPEC #<SPEC #x2088E85E>) 
(M :AROUND (BEFORE) BASE #<SPEC #x2088E85E>) 
(M :BEFORE SPEC #<SPEC #x2088E85E>) 
(M :BEFORE BASE #<SPEC #x2076B0FE>) 
(M SPEC (BEFORE) #<SPEC #x2076B0FE>) 
(M BASE #<SPEC #x2076B0FE>) 
(M SPEC (AFTER) #<SPEC #x2076B0FE>) 
(M :AFTER BASE #<SPEC #x2076B0FE>) 
(M :AFTER SPEC #<SPEC #x2076B0FE>) 
(M :AROUND (AFTER) BASE #<SPEC #x2076B0FE>) 
(M :AROUND (AFTER) SPEC #<SPEC #x2076B0FE>) 
(M BASE #<SPEC #x2076B0FE>)




-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.