CLOS中的(:before /:after)方法调用顺序?

时间:2011-12-03 23:14:46

标签: lisp common-lisp clos

我需要一些帮助来理解以下代码的执行顺序。

我使用以下内容创建pie的实例:

(cook (make-instance 'pie))

我知道lisp执行从最具体到最不具体的函数。但是,在(defmethod cook ((p pie))被调用之后,它看起来并不像是在遵循。

我会假设(defmethod cook :after ((f food))& (defmethod cook :after ((p pie))以相反的顺序执行,因为我们的实例是pie,而不是父类food

谢谢, 任何输入将不胜感激。

(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))

输出如:

"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)

2 个答案:

答案 0 :(得分:4)

section 7.6.6.2 (Standard Method Combination) of the Common Lisp HyperSpec。这是最相关的段落:

  

之前的方法以最特定的第一顺序运行   方法以最少特定的第一顺序运行之后。该设计   可以用一个例子来说明这种差异的基本原理。   假设类C1修改其超类C2的行为   在方法之前和之后添加方法。是否行为   C2类直接由C2上的方法定义,或者从C2继承   超类不会影响调用的相对顺序   C1类实例的方法。方法运行之前的C1类   在所有C2类方法之前。 C1之后的方法运行   所有C2类的方法。

答案 1 :(得分:3)

  • 主要方法首先执行最具体,然后通过CALL-NEXT-METHOD执行下一个具体方法。

  • :before方法首先执行最具体的方法。

  • :after方法执行最少特定优先。