The print and pprint Modules¶
The IO library’s printing modules provide an interface that outputs an object in Dylan literal syntax if the object can be represented as a Dylan literal, and otherwise, outputs the object in an implementation-dependent manner.
There are two functions, print
and print-object
. The
print
function accepts keyword arguments that form a print request,
controlling features such as circular printing, how deep within a data
structure to print, how many elements in long sequences to print before using
an ellipsis notation, whether pretty printing is desired, and so on. Users
extend print
’s ability to print various objects by adding methods to
the print-object
generic function.
The print
function handles most of the overhead to satisfy special
print requests, outputting any special notations required, and it only calls
print-object
when it is necessary to print objects. Users should always
call the print
function to output objects, especially recursively from
within print-object
methods, to output an object’s components. Users
should never call print-object
directly.
The IO library exports two modules for use with printing, print and pprint. Reference entries for the interfaces exported from the print module can be found in The print Module, and reference entries for interfaces exported from the pprint module are in The pprint Module.
These modules use the Streams module. See The streams Module for full details of the Streams module.
Print functions¶
The Print module offers functions for users to call to print objects,
print
and print-to-string
, along with interfaces that allow you
to modify the way your own objects are printed: print-object
and
printing-object
.
The Print module exports the following variables which provide default values for calls to the print function. Their values are implementation-dependent.
Pretty printing¶
When writing print-object
methods, you can ignore whether pretty
printing is in effect. If you write your print-object
method using
pretty printing functions, then when pretty printing is in effect, the
output is pretty printed. When pretty printing is not in effect, your
method produces output as though you had not written it to use pretty
printing. All print-object
methods that are written to do pretty
printing must call the pretty printing functions within the dynamic
scope of a call to pprint-logical-block; otherwise, the pretty
printing functions are no-ops.
The following interfaces are exported from the pprint module:
The print Module¶
This section contains a reference entry for each item exported from the IO library’s print module.
- print Function¶
Prints object to the specified stream.
- Signature:
print object stream #key circle? escape? length level pretty? => ()
- Parameters:
object – An instance of
<object>
.stream – An instance of
<stream>
.circle? (#key) – An instance of
<boolean>
. Default value:*print-circle?*
.escape? (#key) – An instance of
<boolean>
. Default value:*print-escape?*
.level (#key) –
#f
or an instance of<integer>
. Default value:*print-level*
.length (#key) –
#f
or an instance of<integer>
. Default value:*print-length*
.pretty? (#key) – An instance of
<boolean>
. Default value:*print-pretty?*
.
- Discussion:
Prints object to stream according to the print request formed by the keyword arguments. A first call to print creates a printing stream to represent the print request, and recursive calls to print on this printing stream process the keyword arguments differently (see below). There are inspection functions for querying the print request. When
print
actually prints an object, it callsprint-object
. Though the inspection functions for querying the print request allow you to inspect any parameter of the print request,print-object
methods should only need to callprint-length
. All other aspects of the print request are handled byprint
. There is one exception, which is described in Pretty printing.The level keyword controls how deep into a nested data structure to print. The value
#f
indicates that there is no limit. The default,*print-level*
, has no effect on recursive calls toprint
. Recursive calls toprint
may change the value of print-level explicitly, butprint
always uses a value to ensure the print request formed by the first call toprint
is never exceeded. For example, if a first call toprint
set the level to 5, and while at a depth of 3, a recursive call specified a level of 4, the recursive call would only descend 2 more levels, not 4.The length keyword controls how many elements of a sequence to print before printing ellipsis notation (…). The value
#f
indicates that there is no limit. The print-length control can be interpreted loosely by someprint-object
methods to control how many elements of any kind of object to print; for example, the default<object>
method might regard print-length to determine how many slot-name/value pairs to print. The default,*print-length*
, has no effect on recursive calls toprint
. Recursive calls toprint
may change the value of print-length explicitly, but they may only decrease the value, never increase it.The circle? keyword indicates whether printing should check all subcomponent references to make sure the printing process does not infinitely recurse through a data structure. Circular printing also tags objects that occur more than once when they are first printed, and later occurrences are printed as a reference to the previously emitted tag. The default,
*print-circle?*
, has no effect on recursive calls toprint
. If print-circle? is already#t
, then it remains#t
throughout all recursive calls. If print-circle? is#f
, then recursive calls toprint
can change the value to#t
; however, when printing exits the dynamic scope of the call that changed the value to#t
, the value reverts back to#f
. If the original call toprint
specifies circle? as#f
, and dynamically distinct recursive calls turn circular printing on and off, all output generated while circular printing was on shares the same tagging space; that is, if#1#
is printed twice, once from each of two distinct recursive calls to print, then each#1#
is guaranteed to signify the same==
object.The pretty? keyword indicates whether printing should attempt to insert line breaks and indentation to format objects according to how programmers tend to find it easier to read data. The default,
*print-pretty?*
, has no effect on recursive calls toprint
. If print-pretty? is already#t
, then it remains#t
throughout all recursive calls. If print-pretty? is#f
, then recursive calls toprint
can change the value to#t
; however, when printing exits the dynamic scope of the call that changed the value to#t
, the value reverts back to#f
.The escape? keyword indicates whether printing should show escape codes in strings and, by extension, whether other objects should be printed with additional identifying information.
- *print-circle?* Thread Variable¶
Controls whether or not to detect circular structures when printing.
- Type:
<boolean>
- Value:
- Discussion:
*print-circle?*
holds the default value for whether or not to detect circular structures when printing. When#t
, circularity detection is enabled. The default is#f
.When calling
print
directly,*print-circle?*
may be overridden by specifying a value for thecircle?
argument. It is dynamically bound byprint
so that its value is inherited by recursive calls.Note that when
*print-circle?*
is#t
attempts to print circular structures may result in failure to terminate.- See also:
print
for more detail on how circular structures are handled.
- *print-escape?* Thread Variable¶
Whether to print objects for debugging or for display to the end user.
- Type:
<boolean>
- Value:
- Discussion:
Controls whether or not
print
displays extra identifying information for the object being printed, making it easier to distinguish from other objects of the same type for debugging purposes. For those who know Python, this is much like the difference between__repr__
and__str__
.For example, when
*print-escape?*
is true strings print exactly the way Dylan string literals look, for example"abc\\n"
. When*print-escape?*
is false the same string prints asabc
with a trailing newline.- See also:
- *print-length* Thread Variable¶
Controls the number of elements of an expression to print.
- *print-level* Thread Variable¶
Controls how deeply into a nested expression to print.
- *print-pretty?* Thread Variable¶
Controls whether or not pretty printing is used.
- print-object Open Generic function¶
Prints an object to a stream.
- Signature:
print-object object stream => ()
- Parameters:
- Discussion:
Prints an object to a stream. Extend the ability of
print
to print objects by adding methods to this generic function. Whenprint
actually prints an object, it callsprint-object
.The most common use of this functionality is to change the way objects in your own library display in the debugger, to make individual instances more easily identifiable. See the example under
printing-object
.Never call
print-object
directly.- See also:
printing-object
, which simplifies writingprint-object
methods.
- print-to-string Function¶
Calls
print
on object and returns the result as a string.- Signature:
print-to-string object #key circle? escape? level length pretty? => result
- Parameters:
object – An instance of
<object>
.level (#key) –
#f
or an instance of<integer>
. Default value:*print-level*
.length (#key) –
#f
or an instance of<integer>
. Default value:*print-length*
.circle? (#key) – An instance of
<boolean>
. Default value:*print-circle?*
.pretty? (#key) – An instance of
<boolean>
. Default value:*print-pretty?*
.escape? (#key) – An instance of
<boolean>
. Default value:*print-escape?*
.
- Values:
result – An instance of
<byte-string>
.
- Discussion:
Calls
print
to produce output according to the print request formed by the keyword arguments and returns the result as a string.
- printing-object Macro¶
Wrapper around
printing-logical-block
.- Macro Call:
printing-object(object, stream, #key type? = #t) body end
printing-object may be used within
print-object
to print Dylan objects in a standardized way while adding identifying information for your own classes. Example:define method print-object (acct :: <account>, stream :: <stream>) => () printing-object(acct, stream) print(account-name(acct), stream, escape?: #t); end; end;
With the above method, an
<account>
object with name “foo” will print as{<account> "foo" 123}
where123
is a unique identifier for the object.
The pprint Module¶
This section contains a reference entry for each item exported from the IO library’s pprint module.
- *default-line-length* Variable¶
Controls the default line length used by the pretty printer.
- Type:
<integer>
- Value:
80
- Discussion:
Controls the line length used by the pretty printer to determine how much output will fit on a single line. The value must be an integer.
- pprint-indent Function¶
Specifies the indentation to use within the current logical block.
- Signature:
pprint-indent relative-to n stream => ()
- Parameters:
- Discussion:
Specifies the indentation to use within the current logical block. When relative-to is
#"block"
, thenpprint-indent
sets the indentation to the column of the first character of the logical block plus n. When relative-to is#"current"
, thenpprint-indent
sets the indentation to the current column plus n.
- pprint-logical-block Function¶
Groups printing into a logical block.
- Signature:
pprint-logical-block stream #key prefix per-line-prefix body suffix column => ()
- Parameters:
stream – An instance of
<stream>
.prefix (#key) –
#f
or an instance of<byte-string>
.per-line-prefix (#key) –
#f
or an instance of<byte-string>
.body (#key) – An instance of
<function>
.suffix (#key) –
#f
or an instance of<byte-string>
.column (#key) – A limited instance of
<integer>
, minimum 0.
- Discussion:
Groups printing into a logical block. The logical block provides boundaries for new levels of indentation, affects
#"linear"
newlines, and so on. Prefix is a string to print at the beginning of the logical block. The block’s indentation is automatically set to be one character position greater than the column in which prefix ends. Alternatively, per-line-prefix is a string to print on every line of the logical block. This function signals an error if it is called with both prefix and per-line-prefix supplied as non-#f
. Suffix is a string to print at the end of the logical block. Column advises the pretty printer as to the current column of the output stream (the default is zero). The column argument may be ignored entirely by some methods, and it may be ignored in some cases by methods that can better determine the stream’s current output column.The body keyword must be a function that can take one argument, and this argument is a stream. The body function should use the stream argument passed to it; the body function should not close over the stream argument to
pprint-logical-block
.pprint-logical-block
wraps stream with a pretty printing stream when stream is any other kind of stream. If stream is already a pretty printing stream, then the body function is called on stream.All
print-object
methods that are written to do pretty printing must call the other pretty printing functions within the dynamic scope of a call topprint-logical-block
; otherwise, the pretty printing functions are no-ops.
- pprint-newline Function¶
Announces a conditional newline to the pretty printer.
- Signature:
pprint-newline kind stream => ()
- Parameters:
kind – One of
#"fill"
,#"linear"
,#"miser"
,#"mandatory"
.stream – An instance of
<stream>
.
- Discussion:
Announces a conditional newline to the pretty printer. The pretty printer emits a newline depending on the kind and the state of the pretty printer’s current line buffer. The kind argument has roughly the following meanings:
#"fill"
Emit a newline if the current section of output does not fit on one line.#"linear"
Emit a newline if any#"linear"
newline in the current section needs to be emitted. That is, if a current section of output cannot fit on one line, and any one of the#"linear"
newlines in the section needs to be emitted, then emit them all.#"miser"
Emit a newline as if it were a#"linear"
newline, but only when miser mode is in effect. Miser style is in effect when a logical block starts past a particular column of output.#"mandatory"
Emit a newline always. Establish that any containing sections cannot be printed on a single line so that#"linear"
and#"miser"
newlines will be emitted as appropriate.
- pprint-tab Function¶
Announces a tab to the pretty printer.
- Signature:
pprint-tab kind colnum colinc stream => ()
- Parameters:
- Discussion:
Announces a tab to the pretty printer. The colnum and colinc arguments have meaning based on the value of kind:
#"line"
Tab to output column colnum. If the output is already at or beyond colnum, then add colinc to colnum until printing can continue at a column beyond the end of the output already on the line.#"line-relative"
Output colnum spaces. Then output enough spaces to tab to a column that is a multiple of colinc from the beginning of the line.#"section"
Similar to#"line"
, but column counting is relative to the beginning of the current section rather than the beginning of the line.#"section-relative"
Similar to#"line-relative"
, but column counting is relative to the beginning of the current section rather than the beginning of the line.
- *print-miser-width* Variable¶
Controls miser mode.
- Type:
false-or(<integer>)
- Value:
- Discussion:
Controls miser mode. Pretty printing is in miser mode whenever a logical block (see
pprint-logical-block
) begins in a column of output that is greater than:*default-line-length* - *print-miser-width*
The value must be an integer or
#f
(the default);#f
indicates that the pretty printer should never enter miser mode.