Skip to main content

print-unreadable-object

print-unreadable-object Macro

Syntax:

print-unreadable-object (object stream &key type identity) {form}* → nil

Arguments and Values:

object—an object; evaluated.

stream—a stream designator ; evaluated.

type—a generalized boolean; evaluated.

identity—a generalized boolean; evaluated.

forms—an implicit progn.

Description:

Outputs a printed representation of object on stream, beginning with “#<” and ending with “>”. Everything output to stream by the body forms is enclosed in the the angle brackets. If type is true, the output from forms is preceded by a brief description of the object’s type and a space character. If identity is true, the output from forms is followed by a space character and a representation of the object’s identity, typically a storage address.

If either type or identity is not supplied, its value is false. It is valid to omit the body forms. If type and identity are both true and there are no body forms, only one space character separates the type and the identity.

Examples:

;; Note that in this example, the precise form of the output ;; is *implementation-dependent*. 
(defmethod print-object ((obj airplane) stream)
(print-unreadable-object (obj stream :type t :identity t)
(princ (tail-number obj) stream)))
(prin1-to-string my-airplane)
"#<Airplane NW0773 36000123135>"
<i><sup>or</sup>→</i> "#<FAA:AIRPLANE NW0773 17>"

Exceptional Situations:

If *print-readably* is true, print-unreadable-object signals an error of type print-not-readable without printing anything.

Expanded Reference: print-unreadable-object

Basic Usage

print-unreadable-object prints an object using the #<...> notation. It is typically used inside print-object methods.

(defclass widget ()
((id :initarg :id :accessor widget-id)))

(defmethod print-object ((w widget) stream)
(print-unreadable-object (w stream)
(format stream "WIDGET id=~A" (widget-id w))))

(make-instance 'widget :id 42)
==> #<WIDGET id=42>

Using :type and :identity

The :type option prints the object's type, and :identity prints an implementation-specific identity (typically memory address).

(defclass gadget ()
((name :initarg :name :accessor gadget-name)))

;; With :type t -- prints the class name
(defmethod print-object ((g gadget) stream)
(print-unreadable-object (g stream :type t)
(princ (gadget-name g) stream)))

(make-instance 'gadget :name "Sprocket")
==> #<GADGET Sprocket>

;; With both :type and :identity
(defmethod print-object ((g gadget) stream)
(print-unreadable-object (g stream :type t :identity t)
(princ (gadget-name g) stream)))

(make-instance 'gadget :name "Sprocket")
==> #<GADGET Sprocket {1003AB0123}>

Empty Body with :type and :identity

When no body forms are given, only the type and/or identity are printed.

(defclass token () ())

(defmethod print-object ((tok token) stream)
(print-unreadable-object (tok stream :type t :identity t)))

(make-instance 'token)
==> #<TOKEN {1004CD0003}>

Signals Error Under print-readably

If *print-readably* is true, print-unreadable-object signals a print-not-readable error rather than printing unreadable output.

(defclass opaque () ())

(defmethod print-object ((o opaque) stream)
(print-unreadable-object (o stream :type t)))

(handler-case
(let ((*print-readably* t))
(prin1-to-string (make-instance 'opaque)))
(print-not-readable (c)
(format nil "Cannot print ~S readably"
(type-of (print-not-readable-object c)))))
=> "Cannot print OPAQUE readably"