Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of (:before/:after) method invocation in CLOS?

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)
like image 298
Gregorio Di Stefano Avatar asked Nov 18 '25 05:11

Gregorio Di Stefano


2 Answers

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.

like image 192
Rörd Avatar answered Nov 20 '25 05:11

Rörd


  • 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.

like image 38
Rainer Joswig Avatar answered Nov 20 '25 03:11

Rainer Joswig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!