2

我正在尝试在(SBCL)Common Lisp 中编写一个小游戏,使用 Quickload 和 ASDF 来定义和管理依赖项。它使用 CLOS,所以我在projectcalledclasses中有一个目录,其中有一个文件locatable.cl.

LOCATABLE 类的defclass表单需要一个 LOCATOR 参数,所以我有一行:

:initform (error "Must supply a locator parameter for this class.")

但是,每当我尝试加载此文件或quickload系统时,都会收到上述错误(“必须为此类提供定位器参数”)。由于我试图定义一个系统而不是创建该类的任何实例,所以我不明白我为什么会得到这个。如果我注释掉错误行,一切都很好,但我被引导相信我拥有它的方式是需要:initval一个插槽的标准方式。

您如何定义这样的事情,以便您可以加载文件/进行系统定义而不实际发出错误信号?

这是课程 -

(defclass locatable ()
  ((zone
    :accessor zone
    :initform nil)
   (locator
    :initarg :locator
    :initform (error "Must supply a locator parameter for this class.")
    :allocation :class
    :accessor locator)))

更新:我在 REPL 输入了表格并得到了同样的错误。出于好奇,我再次输入了两次,第一次使用:initform "",然后使用错误表单。它接受了第一种形式,并没有抱怨第二种形式,所以这个问题似乎不会在重新定义时发生。

4

1 回答 1

1
(defclass locatable ()
  ((zone
    :accessor zone
    :initform nil)
   (locator
    :initarg :locator
    :initform (error "Must supply a locator parameter for this class.")
    :allocation :class
    :accessor locator)))

插槽locator在课堂上共享。它将以某种方式在类对象中分配。DEFCLASS表单创建了这个类对象。因此,插槽locator通常会在创建和初始化类对象时被初始化。在创建该类的第一个实例之前。

LispWorks 回溯

CL-USER 50 : 1 > :b
Call to CLOS::CLASS-REDEFINITION-LOCK-DEBUGGER-WRAPPER
Call to INVOKE-DEBUGGER
Call to ERROR
Call to (METHOD CLOS::COMPUTE-CLASS-SLOT-CONSES (STANDARD-CLASS))
Call to (METHOD SHARED-INITIALIZE :AFTER (STANDARD-CLASS T))    ; <--
Call to CLOS::ENSURE-CLASS-USING-CLASS-INTERNAL
Call to (METHOD CLOS:ENSURE-CLASS-USING-CLASS (CLASS T))
Call to CLOS::ENSURE-CLASS-WITHOUT-LOD
Call to LET
Call to LET
Call to EVAL
Call to CAPI::CAPI-TOP-LEVEL-FUNCTION
Call to CAPI::INTERACTIVE-PANE-TOP-LOOP
Call to MP::PROCESS-SG-FUNCTION

如您所见SHARED-INITIALIZE,在类对象上调用,然后初始化共享槽。

我也不认为error应该在用户代码中进行这样的调用。您可能会找到一种更好的方法来检查缺少的 initargs。

于 2015-03-31T20:08:25.130 回答