The problem usually occurs if I have a class containing, for example, a pair of slots that will be filled with vectors. If I want to make an object of this class more or less transparent, I implement for it print-object. And here I ran into a problem:
- If I print everything in one line, the REPL heuristic is not good enough to determine how to organize the printable parts in several lines, as a result of which everything will be shifted to the right (see the example below).
- If I decided to split the output into several lines manually, I had a problem with how to indent correctly, so if this object is part of another object, indents are saved (see the example below for clarity).
Here is the code. Consider two classes:
(defclass foo ()
((slot1 :initarg :slot1)
(slot2 :initarg :slot2)))
(defclass bar ()
((foo-slot :initarg :foo)))
And I have the following instances:
(defparameter *foo*
(make-instance 'foo
:slot1 '(a b c d e f g h i j k l m n o p q r s t u v)
:slot2
(defparameter *bar*
(make-instance 'bar
:foo *foo*))
, :
> *bar*
foo-slot =
slot1 = (A B C D E F G H I J K L M N O P Q R S T U V)
slot2 =
1:
print-object :
(defmethod print-object ((obj foo) out)
(with-slots (slot1 slot2) obj
(print-unreadable-object (obj out :type t)
(format out "slot1 = ~A slot2 = ~A" slot1 slot2))))
(defmethod print-object ((obj bar) out)
(with-slots (foo-slot) obj
(print-unreadable-object (obj out :type t)
(format out "foo-slot = ~A" foo-slot))))
:
> *foo*
#<FOO slot1 = (A B C D E F G H I J K L M N O P Q R S T U V) slot2 =
6 7 8)>
> *bar*
#<BAR foo-slot =
2
3
4
5
6
7
8)>>
2:
, , :
(defmethod print-object ((obj foo) out)
(with-slots (slot1 slot2) obj
(print-unreadable-object (obj out :type t)
(format out "~%~Tslot1 = ~A~%~Tslot2 = ~A" slot1 slot2))))
(defmethod print-object ((obj bar) out)
(with-slots (foo-slot) obj
(print-unreadable-object (obj out :type t)
(format out "~%~Tfoo-slot = ~A" foo-slot))))
, *foo* OK, *bar* :
> *foo*
slot1 = (A B C D E F G H I J K L M N O P Q R S T U V)
slot2 = #(1 2 3 4 5 6 7 8)>
*bar*
foo-slot = #<FOO
slot1 = (A B C D E F G H I J K L M N O P Q R S T U V)
slot2 = #(1 2 3 4 5 6 7 8)>>
print-indent, ( , , , SBCL 1.2.14).
( ) ?