Lisp: How to override default string representation for CLOS class?
Asked Answered
J

3

17

In Common Lisp, how can I override the default string representation of a CLOS class so that calls to format or princ will print something intelligible, even when objects of that class are embedded within other types, such as lists or arrays?

For example, if I call (format t "~a~%" x) when x holds an instance of my solution class, I want it to print something like #<SOLUTION genes: #(1 2 3) scores: #(4 5) rank: 6> instead of #<SOLUTION {BB7CD31}>.

So far, all I have managed to figure out is writing custom functions to handle printing structures that I know will contain instances of this class, but this is tedious. Surely Lisp provides some way to get this functionality for free?

Judo answered 11/9, 2011 at 23:52 Comment(0)
C
13

Check out print-object.

Cis answered 12/9, 2011 at 0:57 Comment(2)
This was what I needed. As a stylistic question, what is the "best" way to print to the passed stream inside this method? I am currently using format, but it seems strange to call the function that may very well be calling this method.Judo
format won't call your method recursively by itself - that's something you'd have to do. Also, many, many CL projects have examples of print-object methods. Browse through them to see how other projects typically define them.Lemoine
A
18

You should be looking at print-object and print-unreadable-object. Suppose you have a class named FOO like so:

(defclass foo ()
  ((name :accessor foo-name)))

And you want to print instances like this: #<FOO "xyz"> where "xyz" is the content of slot name. In this case, the following implementation of print-object would do what you want:

(defmethod print-object ((obj foo) out)
  (print-unreadable-object (obj out :type t)
    (format out "~s" (foo-name obj))))
Aconite answered 12/9, 2011 at 3:20 Comment(0)
C
13

Check out print-object.

Cis answered 12/9, 2011 at 0:57 Comment(2)
This was what I needed. As a stylistic question, what is the "best" way to print to the passed stream inside this method? I am currently using format, but it seems strange to call the function that may very well be calling this method.Judo
format won't call your method recursively by itself - that's something you'd have to do. Also, many, many CL projects have examples of print-object methods. Browse through them to see how other projects typically define them.Lemoine
D
1

If you also look 22.1.3.13 Printing Other Objects it suggests print-unreadable-object as a common format macro for such situations

Derward answered 1/7, 2012 at 11:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.