Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unexpected inheritance of slot (values) using errors

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

I would now expect:

(make-instance 'e1)
e1
winner

(make-instance 'e2)
e2
loser

but instead i get

(make-instance 'winner:e1)
e1
winner

(make-instance 'loser:e2)
e1
loser

which is is quite unexpected. What error am I making?

like image 656
Sim Avatar asked Dec 27 '22 05:12

Sim


1 Answers

That's relatively easy to see if you use 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"

What you see is that the object has three (!) slots: WINNER::NAME, PACKAGE and LOSER::NAME.

Why is that? PACKAGE is a symbol in the package CL (PACKAGE is a system class, a type, in Common Lisp). Since both your package use CL, the both have the same symbol PACKAGE and thus there is only one slot of name CL:PACKAGE.

NAME is a symbol local to each of your package. Each package has its own symbol name. Thus each object has two different slots WINNER::NAME and LOSER::NAME.

Since your printer function only reads the slot WINNER::NAME, you only get its content.

What do you need to keep in mind?

  • having a custom printer is fine, but use DESCRIBE for debugging
  • packages are namespaces for symbols. They are not modules for concepts like classes, slots, functions.
  • the package CL comes with many symbols. If your packages uses the package CL, then it has all these symbols. Whether you use them for function names, variables, class names, slot names, ... does not matter.
like image 159
Rainer Joswig Avatar answered Dec 28 '22 23:12

Rainer Joswig