(defpackage :winner
(:use :cl)
(:export e1))
(in-package :winner)
(define-condition e1 ()
((name
:initform "e1"
:reader name)
(package
:initform "winner"
:reader related-package)))
(defmethod print-object ((err e1) stream)
(FORMAT stream "~a~%~a~%" (name err) (related-package err)))
(defpackage :loser
(:use :cl :winner)
(:export e2))
(in-package :loser)
(define-condition e2 (e1)
((name
:initform "e2")
(package
:initform "loser")))
我现在期待:
(make-instance 'e1)
e1
winner
(make-instance 'e2)
e2
loser
但我得到了
(make-instance 'winner:e1)
e1
winner
(make-instance 'loser:e2)
e1
loser
这是非常意外的。 我犯了什么错误?
答案 0 :(得分:10)
如果您使用DESCRIBE
,则相对容易看到。
? (make-instance 'loser:e2)
e1
loser
? (describe *)
e1
loser
Class: #<STANDARD-CLASS LOSER:E2>
Wrapper: #<CCL::CLASS-WRAPPER LOSER:E2 #x302000ECE15D>
Instance slots
WINNER::NAME: "e1"
PACKAGE: "loser"
LOSER::NAME: "e2"
你看到的是该对象有三个(!)插槽:WINNER::NAME
,PACKAGE
和LOSER::NAME
。
为什么? PACKAGE
是包CL
中的符号(PACKAGE
是一个系统类,一个类型,在Common Lisp中)。由于您的包都使用CL,因此两者都具有相同的符号PACKAGE
,因此只有一个名为CL:PACKAGE
的插槽。
NAME
是每个包的本地符号。每个包都有自己的符号名称。因此,每个对象都有两个不同的插槽WINNER::NAME
和LOSER::NAME
。
由于您的打印机功能仅读取插槽WINNER::NAME
,因此您只能获取其内容。
您需要记住什么?
DESCRIBE
进行调试CL
附带了许多符号。如果您的包使用包CL
,那么它包含所有这些符号。是否将它们用于函数名,变量,类名,插槽名,......无关紧要。