3

次のコードの実行順序を理解するのに助けが必要です。

pie以下を使用して、のインスタンスを作成します。

(cook (make-instance 'pie))

私はlispが最も具体的なものから最も具体的でないものまで関数を実行することを知っています。しかし、それ(defmethod cook ((p pie))は呼び出された後に続いているようには見えません。

インスタンスはのであり、親クラスではないため、 (defmethod cook :after ((f food))(defmethod cook :after ((p pie))は逆の順序で実行されると想定 します。piefood

おかげで、どんな入力でも大歓迎です。

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

2 に答える 2

4

Common Lisp HyperSpecのセクション7.6.6.2(標準メソッドの組み合わせ)を参照してください。最も関連性の高い箇所は次のとおりです。

beforeメソッドは最も具体的な最初の順序で実行され、afterメソッドは最も具体的でない最初の順序で実行されます。この違いの設計根拠は、例を使用して説明できます。クラスC1が、beforeメソッドとafterメソッドを追加することにより、そのスーパークラスC2の動作を変更するとします。クラスC2の動作がC2のメソッドによって直接定義されているか、そのスーパークラスから継承されているかは、クラスC1のインスタンスでのメソッドの呼び出しの相対的な順序には影響しません。クラスC1のbeforeメソッドは、クラスC2のすべてのメソッドの前に実行されます。クラスC1のafterメソッドは、クラスC2のすべてのメソッドの後に実行されます。

于 2011-12-04T00:26:30.740 に答える
3
  • 主要なメソッドは、最初に最も具体的に実行され、次にを介して実行されCALL-NEXT-METHODます。

  • :beforeメソッドは最も具体的に最初に実行されます。

  • :afterメソッドは、最小固有優先で実行されます。

于 2011-12-04T00:27:03.930 に答える