获取类优先级列表时的未绑定槽?

时间:2015-09-13 14:18:22

标签: common-lisp sbcl clos mop

为什么我不能在sbcl中获得简单的类优先级列表?

* (sb-mop::class-precedence-list (find-class 'cons));;works

(#<BUILT-IN-CLASS CONS> #<BUILT-IN-CLASS LIST> #<SB-PCL:SYSTEM-CLASS SEQUENCE>
 #<SB-PCL:SYSTEM-CLASS T>)
* (defclass my-class ()    nil)
* (sb-mop::class-precedence-list (find-class 'my-class))

debugger invoked on a UNBOUND-SLOT in thread
#<THREAD "main thread" RUNNING {10039CE8D3}>:
  The slot SB-PCL::%CLASS-PRECEDENCE-LIST is unbound in the object
  #<STANDARD-CLASS MY-CLASS>.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [USE-VALUE  ] Return a value as the slot-value.
  1: [STORE-VALUE] Store and return a value as the slot-value.
  2: [ABORT      ] Exit debugger, returning to top level.

((:METHOD SLOT-UNBOUND (T T T)) #<unavailable argument> #<STANDARD-CLASS MY-CLASS> SB-PCL::%CLASS-PRECEDENCE-LIST) [fast-method]
0] 2

1 个答案:

答案 0 :(得分:4)

课程定稿

来自MOP说明:

类完成是计算类从其超类继承并准备实际分配类的实例的信息的过程。类完成过程包括计算类的类优先级列表,类的实例中可访问的完整插槽集以及类的完整默认初始化参数集。这些值与类元对象相关联,可以通过调用适当的阅读器来访问。此外,类完成过程会决定如何实现类的实例。

为了支持前向引用的超类,并考虑到并非所有类都实际被实例化的事实,类完成不是作为类元对象初始化的一部分完成的。相反,最终化是作为单独的协议完成的,通过调用泛型函数finalize-inheritance来调用。调用finalize-inheritance的确切点取决于类metaobject的类;对于标准类,在定义所有类超类之后的某个时间调用它,但不迟于分配类的第一个实例时(通过allocate-instance)。

类完成的第一步是计算类优先级列表。首先执行此操作允许后续步骤访问类优先级列表。通过调用泛型函数compute-class-precedence-list来执行此步骤。此调用返回的值与类元对象关联,可以通过调用class-precedence-list泛型函数来访问。

...

示例

* (defclass my-class () nil)

#<STANDARD-CLASS MY-CLASS>
* (sb-mop:class-finalized-p (find-class 'my-class))

NIL
* (sb-mop:finalize-inheritance (find-class 'my-class))

NIL
* (sb-mop:class-finalized-p (find-class 'my-class))

T
* (sb-mop:class-precedence-list (find-class 'my-class))

(#<STANDARD-CLASS MY-CLASS> #<STANDARD-CLASS STANDARD-OBJECT>
 #<SB-PCL::SLOT-CLASS SB-PCL::SLOT-OBJECT> #<SB-PCL:SYSTEM-CLASS T>)