Re: [CLOS] Ensuring a method exists





Didier Verna wrote:
Lars Rune Nøstdal <larsnostdal@xxxxxxxxx> wrote:


This seems to work:

(defclass SomeBase ()
())


(defmethod initialize-instance :before ((some-base SomeBase) &key)
(format t "Checking for `foo': ~A~%"
(find-method #'foo '() (mapcar #'find-class
(list (type-of some-base)
(type-of some-base))))))


(defmethod foo ((a SomeBase) (b SomeBase))
(write-line "(foo SomeBase SomeBase)"))


(defclass SomeDerived (SomeBase)
())



That's a nice solution but it has one caveat (my question was probably
not clear enough about this): your trick checks for the existence of a method
only for the class you instanciate, and not for the subclasses.

So imagine having A <- B and creating only instances of B. The lack of method
for class A would go unnoticed. But I want the check for the whole hierarchy
(consider for instance that I'm using the AND method combination type and I'm
expecting an implementation for all the classes).


How portable does it have to be? If not, maybe your Lisp has something like ACL's:

(method-specializers
(find-method #'make-style-font nil
(list (find-class 'gui-style-ftgl))))

-> (#<STANDARD-CLASS GUI-STYLE-FTGL>)

So you could check that you did not get something specialized on a superclass.

Another trick, as long as you are inventing requirements that fly in the face of CLOS (if there is a method for superX, than one /has/ been provided for subX!), is to simplify things for users by providing macrology that (a) defines a method X and (b) records the meta-fact as a symbol property or something.

Of course the big question no one will ask is why you want to do this. Sounds like bad design. But you are not alone, we get people wanting to do this almost as often as we get people trying to fix the parens.

:)

kt


--
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
-- Smiling husband to scowling wife, New Yorker cartoon
.



Relevant Pages