When I define a class -- for example
(defclass foo () ((a :initform 0) (b :initform 1)))
it is printed opaquely, eg
CL> (make-instance 'foo)
#<FOO {B0F3321}>
I have learned how to write print-object methods for my own classes,
but I wonder if there is a "default" method I could use (would be
especially useful when I haven't finalized the class hierarchy and I
am just writing exploratory code).
Thanks,
Tamas
On 2007-07-09, Tamas Papp <······@gmail.com> wrote:
> I have learned how to write print-object methods for my own classes,
> but I wonder if there is a "default" method I could use (would be
> especially useful when I haven't finalized the class hierarchy and I
> am just writing exploratory code).
You could invent a structure-like syntax, and query the class for its
slots using the MOP.
CL-USER> (make-instance 'foo :b (make-instance 'foo :a 5))
#.(MAKE-INSTANCE 'FOO :A 0 :B #.(MAKE-INSTANCE 'FOO :A 5 :B 1))
(defclass foo ()
;; note added :INITARGs for MAKE-INSTANCE
((a :initform 0 :initarg :a)
(b :initform 1 :initarg :b)))
;;; Method specialized on FOO, but could be used for any other class.
;;; (Change SB-MOP to your implementation's MOP package as appropriate.)
(defmethod print-object ((object foo) stream)
(if (and *print-pretty* *read-eval*)
(let* ((class (class-of object))
(slots (remove-if-not #'sb-mop:slot-definition-initargs
(sb-mop:class-slots class))))
(pprint-logical-block (stream nil :prefix "#.(" :suffix ")")
(format stream "~A '~A" 'make-instance (class-name class))
(let ((remaining-slots slots))
(when remaining-slots
(write-char #\space stream)
(pprint-newline :linear stream)
(loop
(pprint-pop)
(let* ((slot (pop remaining-slots))
(name (sb-mop:slot-definition-name slot))
(value (slot-value object name))
(initarg
(car (sb-mop:slot-definition-initargs slot))))
(write initarg :stream stream)
(write-char #\space stream)
(pprint-newline :miser stream)
(unless (constantp value)
(write-char #\' stream))
(write value :stream stream)
(when (null remaining-slots)
(return))
(write-char #\space stream)
(pprint-newline :linear stream)))))))
;; trivial fallback, could be more fancy
(print-unreadable-object (object stream))))