I came across some strange behaviour when trying to customize the print-object
function of a CLOS object. The function does generate the intended string, but it appears outside the object definition (i.e. <OBJECT-NAME >
followed by the string I wanted after the >
character). The skeleton code below reproduces the issue:
(defclass object () ;;; Define some object...
((element-count
:initarg :element-count
:accessor n)
(first-element
:initform nil
:accessor 1st)
(last-element
:initform nil
:accessor end)))
(defmethod print-object ((obj object) stream) ;;; ...and then its print-object method
(print-unreadable-object (obj stream :type t))
(with-accessors ((first 1st)
(last end)
(n n))
obj
(format stream " ~[empty~:;:elements ~:*~d :content ~:*(~[~;~a~;~a ~a~:;~a ... ~a~])~]"
n first last)))
The output strings appear thus:
(defvar o1 (make-instance 'object :element-count 0)) => #<OBJECT > empty
(defvar o2 (make-instance 'object :element-count 1)) => #<OBJECT > :elements 1 :content (NIL)
(defvar o3 (make-instance 'object :element-count 2)) => #<OBJECT > :elements 2 :content (NIL NIL)
(defvar o4 (make-instance 'object :element-count 10)) => #<OBJECT > :elements 10 :content (NIL ... NIL)
I don't understand this output. Per the docs, printing outside the space shouldn't ever happen. Or should it? Well, over to you! By the way, I'm using SBCL on Portacle in Windows.