Question

I need some help understanding the order of execution for the following code.

I create an instance of pie, using the following:

(cook (make-instance 'pie))

I know lisp executes functions from most specific to least specific.. however, it doesn't look like that is being followed after (defmethod cook ((p pie)) is called.

I would assume (defmethod cook :after ((f food)) & (defmethod cook :after ((p pie)) to be executed in opposite order, since our instance is of pie, and not the parent class, food.

Thanks, any input will be greatly appreciated.

(defclass food () ())

(defmethod cook :before ((f food))
  (print "A food is about to be cooked."))

(defmethod cook :after ((f food)) 
  (print "A food has been cooked."))

(defclass pie (food)
  ((filling :accessor pie-filling
            :initarg :filling 
            :initform 'apple)))

(defmethod cook ((p pie))
  (print "Cooking a pie.")
  (setf (pie-filling p) (list 'cooked (pie-filling p))))

(defmethod cook :before ((p pie))
  (print "A pie is about to be cooked."))

(defmethod cook :after ((p pie)) 
  (print "A pie has been cooked."))
  (setq pie-1 (make-instance 'pie :filling 'apple))

With output such as :

"A pie is about to be cooked." 
"A food is about to be cooked." 
"Cooking a pie." 
"A food has been cooked." 
"A pie has been cooked." 
(COOKED APPLE)
Was it helpful?

Solution

See section 7.6.6.2 (Standard Method Combination) of the Common Lisp HyperSpec. Here's the most relevant passage:

The before methods are run in most-specific-first order while the after methods are run in least-specific-first order. The design rationale for this difference can be illustrated with an example. Suppose class C1 modifies the behavior of its superclass, C2, by adding before methods and after methods. Whether the behavior of the class C2 is defined directly by methods on C2 or is inherited from its superclasses does not affect the relative order of invocation of methods on instances of the class C1. Class C1's before method runs before all of class C2's methods. Class C1's after method runs after all of class C2's methods.

OTHER TIPS

  • The primary methods are executed most-specific first, then the next specific via CALL-NEXT-METHOD.

  • the :before methods are executed most-specific-first.

  • the :after methods are execute least-specific-first.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top