理解 CLOS:后续方法和主要方法

Vin*_*inn 2 sbcl common-lisp clos generic-function method-combination

在 hunchentoot 源代码中,有一个:after名为initalize-instance 的def 方法。

这个特定的示例是整个项目中调用的少数:after方法之一。initalize-instance

我使用 CLOS 的经验告诉我, 需要一个主要方法:before:after并且:around可以使用方法。

但在 hunchentoot 包中,我看不到他们如何创建主要方法以使这些:after方法起作用。

我缺少什么?

Rai*_*wig 5

符号initalize-instanceCOMMON-LISP包装内。它是标准提供的通用功能之一。如果你检查这个通用函数,你会发现它有很多方法。还有一个匹配的主要方法。方法可以在任何地方声明,不需要在特定文件中。

CL-USER 9 > (defclass my-class () (a b))
#<STANDARD-CLASS MY-CLASS 8010021793>

CL-USER 10 > (defmethod initialize-instance :after ((instance my-class)
                                                    &rest initargs &key)
               (print `(:aftermethod for initialize-instance
                        of class my-class
                        and instance ,instance)))
#<STANDARD-METHOD INITIALIZE-INSTANCE (:AFTER) (MY-CLASS) 8010027193>

CL-USER 11 > (make-instance 'my-class)

(:AFTERMETHOD FOR INITIALIZE-INSTANCE OF CLASS
 MY-CLASS AND INSTANCE #<MY-CLASS 80103A979B>) 
#<MY-CLASS 80103A979B>
Run Code Online (Sandbox Code Playgroud)

initialize-instance与类对象的方法组合my-class如下所示:

MULTIPLE-VALUE-PROG1
 CALL-METHOD
  (METHOD INITIALIZE-INSTANCE (STANDARD-OBJECT))
 CALL-METHOD
  (METHOD INITIALIZE-INSTANCE :AFTER (MY-CLASS))
Run Code Online (Sandbox Code Playgroud)

主要方法STANDARD-OBJECT是系统提供的。

CL-USER 12 > (typep * 'standard-object)
T
Run Code Online (Sandbox Code Playgroud)

上面显示该实例也是类的standard-object,因为standard-object它是 的超类my-class

CL-USER 13 > (class-direct-superclasses (find-class 'my-class))
(#<STANDARD-CLASS STANDARD-OBJECT 80D01BCA7B>)
Run Code Online (Sandbox Code Playgroud)

该类standard-object是该类的超类my-class