Порядок вызова метода (: before /: after) в CLOS? - PullRequest
3 голосов
/ 04 декабря 2011

Мне нужна помощь в понимании порядка выполнения для следующего кода.

Я создаю экземпляр 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 ]

4 голосов
/ 04 декабря 2011

См. раздел 7.6.6.2 (Стандартная комбинация методов) Common Lisp HyperSpec . Вот наиболее релевантный отрывок:

Методы before запускаются в наиболее специфичном порядке, а после того, как методы выполняются в порядке наименьшей специфичности Дизайн Обоснование этой разницы можно проиллюстрировать на примере. Предположим, что класс C1 изменяет поведение своего суперкласса C2 добавление до методов и после методов. Будь то поведение класс C2 определяется непосредственно методами на C2 или наследуется от его суперклассы не влияют на относительный порядок вызова методы на экземплярах класса C1. Класс C1 перед запуском метода перед всеми методами класса C2. Метод класса C1 работает после все методы класса C2.

3 голосов
/ 04 декабря 2011
  • Первичные методы выполняются сначала наиболее специфично, а затем специфично через CALL-NEXT-METHOD.

  • методы :before выполняются в первую очередь по специфике.

  • методы :after выполняются в первую очередь наименее специфичными.

...