Re: CLOS question
- From: Alan Crowe <alan@xxxxxxxxxxxxxxxxxxxxxxx>
- Date: 30 Jul 2007 18:13:43 +0100
Rainer Joswig <joswig@xxxxxxxxxxxxxx> writes:
In article <f8j0o8$8qc$1@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx>,
stamant@xxxxxxxx (Rob St. Amant) wrote:
I have what seems like a familiar CLOS question, but a quick Google
search doesn't turn up an answer: I have a method, m, and an after
method for it. The after method is specialized on class c. I'd like
to define a class d that inherits c, and have instances of d behave
just like instances of c *except* for that single after method.
I don't believe that I can prevent the after method for class c from
being run when m is called on an instance of d.
Right. All :after methods will be executed.
(Though it would be
convenient if I were wrong about this.) My question is about the
choices for design. I could break class c into two classes, c1 and
c2, and only define the after method for c2, and have d inherit c1,
but I'm wondering if there are other reasonable designs.
Then you get to a more Mixin-style of programming.
Other options:
* use another method combination, maybe write your own one
It might look like this:
#| frame method combination runs the most specific :open method if any, the
most specific primary method, and the most specific :close method if any,
finally return the result of the primary method. Less specific primary methods
are runnable via call next method.
The key words are :open and :close leaving :before and :after available for
use in a more elaborate version. |#
(define-method-combination frame ()
((open (:open))
(primary () :required t)
(close (:close)))
`(progn
(print (list ,(length open) ;remove once debugged
,(length primary)
,(length close)))
,(if open
`(call-method ,(first open))
nil)
(prog1
(call-method ,(first primary)
,(rest primary))
,(if close
`(call-method ,(first close))
nil))))
(defclass c ()())
(defclass d (c)())
(defgeneric act (object)
(:method-combination frame)
(:method ((o c))
(format t "~&Primary method for class C actually working on ~A."
(class-of o))
'C)
(:method :close ((o c))
(format t "~&Close class C, called on class ~A."
(class-of o)))
(:method ((o d))
(format t "~&Primary method for class D called on ~A."
(class-of o))
(if (y-or-n-p "Call next method? ")
(call-next-method)
'that-all-folks)))
With these definitions the close method acts as an after
method,
CL-USER> (act (make-instance 'c))
(0 1 1)
Primary method for class C actually working on #<STANDARD-CLASS C {48B7EBC5}>.
Close class C, called on class #<STANDARD-CLASS C {48B7EBC5}>.
C
we still get the return value from the primary method
The frame combination allows you to call next method
CL-USER> (act (make-instance 'd))
(0 2 1)
Primary method for class D called on #<STANDARD-CLASS D {48BA6EB5}>.
Call next method? y
Primary method for class C actually working on #<STANDARD-CLASS D {48BA6EB5}>.
Close class C, called on class #<STANDARD-CLASS D {48BA6EB5}>.
C
Or not
CL-USER> (act (make-instance 'd))
(0 2 1)
Primary method for class D called on #<STANDARD-CLASS D {48BA6EB5}>.
Call next method? n
Close class C, called on class #<STANDARD-CLASS D {48BA6EB5}>.
THAT-ALL-FOLKS
The point of it is to be able to turn off less specific
close methods
(defmethod act :close ((o d)) nil) ;no closing action for class D
CL-USER> (act (make-instance 'd))
(0 2 2)
Primary method for class D called on #<STANDARD-CLASS D {48BA6EB5}>.
Call next method? n
THAT-ALL-FOLKS
The close method has been turned off for D, but its still
there for C:
CL-USER> (act (make-instance 'c))
(0 1 1)
Primary method for class C actually working on #<STANDARD-CLASS C {48B7EBC5}>.
Close class C, called on class #<STANDARD-CLASS C {48B7EBC5}>.
C
Alan Crowe
Edinburgh
Scotland
.
- Follow-Ups:
- Re: CLOS question
- From: Rob St. Amant
- Re: CLOS question
- References:
- CLOS question
- From: Rob St. Amant
- Re: CLOS question
- From: Rainer Joswig
- CLOS question
- Prev by Date: Re: shootout: implementing an interpreter for a simple procedural language Minim
- Next by Date: Re: I symbolics still selling machines? does anyone use the lisp genera os?
- Previous by thread: Re: CLOS question
- Next by thread: Re: CLOS question
- Index(es):