From: Nicolas Chapados
Subject: Multiple :after methods with same specialization in CLOS
Date: 
Message-ID: <336F5882.478D@nortel.ca>
I'd like to know whether/how it's possible to have several (:after)
methods with the same specialization in CLOS.

The problem I'm facing is that when a new object of a certain class
(let's call it X) is created, I'd like to do two things:

	1. Do some error checking
	2. Register the object with some central list

The obvious solution is to add two :after methods as follows:

(defmethod initialize-instance :after ((my-x X) &rest other-args)
	; do error checking here
	)
(defmethod initialize-instance :after ((my-x X) &rest other-args)
	; do registration here
	)

The problem is that the second method "hides" the first one since
they have the same lambda-list.  Is there a standard way to get both
:after methods to be called?

	Many thanks!
	+ Nicolas

---
Nicolas Chapados			Home: ··········@ieee.ca
Nortel Technology, Montreal, Canada	Work: ········@nortel.ca

From: David Lowry
Subject: Re: Multiple :after methods with same specialization in CLOS
Date: 
Message-ID: <336FAA9B.21AB@dbrc.com>
Nicolas Chapados wrote:
> 
> I'd like to know whether/how it's possible to have several (:after)
> methods with the same specialization in CLOS.
> 
> The problem I'm facing is that when a new object of a certain class
> (let's call it X) is created, I'd like to do two things:
> 
>         1. Do some error checking
>         2. Register the object with some central list
> 
> The obvious solution is to add two :after methods as follows:

Well, the real obvious solution is to do the error checking and object registering in 
one :after method.  Since you're not doing it this way, you probably have some reason
to keep them separate, so see below.

> 
> (defmethod initialize-instance :after ((my-x X) &rest other-args)
>         ; do error checking here
>         )
> (defmethod initialize-instance :after ((my-x X) &rest other-args)
>         ; do registration here
>         )
> 
> The problem is that the second method "hides" the first one since
> they have the same lambda-list.  Is there a standard way to get both
> :after methods to be called?

If you want two sequential :after methods, add an extra class in your class hierarchy 
chain, right above the class of X.  If a class inherents several :after methods, it does 
each :after method in order from the most specific to the most general.  For example:

(defclass registerable-object () ...)

(defclass error-check-object (registerable-object) ...)

(defclass my-object (error-check-object) ...)

then:

(defmethod initialize-instance :after ((x error-check-object) & rest xxx)
     ;do error checking

	)

(defmethod initialize-instance :after ((x registerable-object) & rest xxx)
     ;do object registering

	)

when you create an instance of <my-object>, it will do the error-check-object :after
method; followed by the registerable-object :after method; from the call to 
initialize-instance.

Hope this is clear.
DDL


-- 

[ David D. Lowry	
[ Attorney at Law (or at Play)				···@dbrc.com
[ Dike, Bronstein, Roberts & Cushman LLP		www.dbrc.com
[ Boston, MA 02109					617 523-3400
[
[ CLOS > (C++ * 10^2)
From: Duncan Smith
Subject: Re: Multiple :after methods with same specialization in CLOS
Date: 
Message-ID: <33700F8E.6E4D@flavors.com>
Nicolas Chapados wrote:
> 
> I'd like to know whether/how it's possible to have several (:after)
> methods with the same specialization in CLOS.

If you don't have one already you can create an :AROUND method
and         do registration after call-next-method.

The other approach is to use define-method-combination to create an
"augmented standard" method combination and add something like :REGISTER
methods to the mix.

-Duncan
From: Kelly Murray
Subject: Re: Multiple :after methods with same specialization in CLOS
Date: 
Message-ID: <5kqpgb$qlg$1@sparky.franz.com>
In article <·············@flavors.com>, Duncan Smith <···@flavors.com> writes:
>> Nicolas Chapados wrote:
>> > 
>> > I'd like to know whether/how it's possible to have several (:after)
>> > methods with the same specialization in CLOS.
>> 
>> If you don't have one already you can create an :AROUND method
>> and         do registration after call-next-method.

Right, :around methods have the most flexibility.

Another option is to have one :after method which then invokes 
another primary method on the objects.  Then :around methods
can be defined for this new primary method.  

(defmethod foo :after ((obj xclass) &rest args)
  (apply #'after-foo obj args))

In the specific case of initialize-instance, 
I believe CLOS has omitted this very useful and needed functionality
by not having exactly such a primary method
executed after all the initialize-instance code ran,
and furthermore didn't need to take the consing and overhead of the &rest initializer args.
I defined and used such a method in all my CLOS code and implementation.
I think it was called (new-instance obj).

>> 
>> The other approach is to use define-method-combination to create an
>> "augmented standard" method combination and add something like :REGISTER
>> methods to the mix.
>> 

I believe Flavors had a predefined :progn method, 
in which any newly defined methods were just added on and didn't
replace any existing ones.

-Kelly
From: Barry Margolin
Subject: Re: Multiple :after methods with same specialization in CLOS
Date: 
Message-ID: <5kpk11$src@pasilla.bbnplanet.com>
In article <·············@nortel.ca>,
Nicolas Chapados  <········@nortel.ca> wrote:
>I'd like to know whether/how it's possible to have several (:after)
>methods with the same specialization in CLOS.

No.  The "name" of a method is the combination of the generic function
name, the list of qualifiers, and the list of specializations.  If you
evaluate a defmethod with the same function name, qualifiers, and
specializations as a previous one, it redefines the method, rather than
adding to it.

As someone else pointed out, if you need to do multiple things in the
:after method for a particular specialization, why can't you simply put
them in one method definition?
-- 
Barry Margolin
BBN Corporation, Cambridge, MA
······@bbnplanet.com
(BBN customers, call (800) 632-7638 option 1 for support)