Next: syslib structs safe final, Previous: syslib structs safe inspect, Up: syslib structs safe [Index]
Vicare’s built–in Scheme objects writer can print structs just fine, handling cyclic references and shared objects:
(import (vicare)) (print-graph #t) (set-port-buffer-mode! (current-output-port) (buffer-mode none)) (define-struct duo (one two)) ;; simple struct (display (make-duo 1 2)) -| #[struct duo one=1 two=2] ;; struct with shared object (let* ((A (make-duo 1 2)) (B (make-duo A A))) (display B)) -| #[struct duo one=#0=#[struct duo one=1 two=2] two=#0#] ;; struct with cyclic reference to itself (let ((A (make-duo 1 (void)))) (set-duo-two! A A) (display A)) -| #0=#[struct duo one=1 two=#0#]
The Scheme objects writer is able to differentiate between
display
, write
and pretty-print
printing. When
printing structs, the built–in writer makes no difference
between printing with display
and write
; it does it
differently when printing with pretty-print
:
(import (vicare)) (print-graph #t) (set-port-buffer-mode! (current-output-port) (buffer-mode none)) (define-struct duo (one two)) ;; simple struct (pretty-print (make-duo 1 2)) -| (struct duo (one 1) (two 2)) ;; struct with shared object (let* ((A (make-duo 1 2)) (B (make-duo A A))) (pretty-print B)) -| (struct duo (one #0=(struct duo (one 1) (two 2))) (two #0#)) ;; struct with cyclic reference to itself (let ((A (make-duo 1 (void)))) (set-duo-two! A A) (pretty-print A)) -| #0=(struct duo (one 1) (two #0#))
Sometimes, we need to print a struct with a customised representation. For example keyword objects (see Keyword objects) are structs with a custom printer function:
(display #:ciao) ⇒ #:ciao
For every struct type it is possible to set a custom printer function;
it accepts 3 arguments: the struct to be printed; a textual
output port into which to write a string representation of the struct in
the style of display
, write
or pretty-print
; a
sub–printer function to be optionally used to print component objects.
The sub–printer function accepts as single argument the object to
print; it allows us to interface with the shared objects printer that
handles shared and cyclic references.
As example, the following code defines a custom printer, making use of
the parameter printer-printing-style
to differentiate the style:
(import (vicare)) (print-graph #t) (set-port-buffer-mode! (current-output-port) (buffer-mode none)) (define-struct duo (one two)) (define (duo-printer stru port sub-printer) (case (printer-printing-style) ((display) (display "#{duo " port) (sub-printer (duo-one stru)) (display " " port) (sub-printer (duo-two stru)) (display "}" port)) ((write) (display "(" port) ;;By using the sub-printer: we make this sexp shared too. (sub-printer '(struct-constructor (struct-type-descriptor duo))) (display " " port) (sub-printer (duo-one stru)) (display " " port) (sub-printer (duo-two stru)) (display ")" port)) ((pretty-print) (sub-printer `(struct duo #:one ,(duo-one stru) #:two ,(duo-two stru)))))) (set-struct-type-printer! (struct-type-descriptor duo) duo-printer) (define O (make-duo 1 2)) (display O) -| #{duo 1 2}" (write O) -| ((struct-constructor (struct-type-descriptor duo)) 1 2) (pretty-print O) -| (struct duo #:one 1 #:two 2) ;; shared object, display (let* ((A (make-duo 1 2)) (B (make-duo A A))) (display B)) -| #{duo #0=#{duo 1 2} #0#} ;; shared object, write (let* ((A (make-duo 1 2)) (B (make-duo A A))) (write B)) -| (#0=(struct-constructor (struct-type-descriptor duo)) \ #1=(#0# 1 2) #1#)
Select the procedure printer as printer for structs of type
std; if printer is #f
, instances of type std
make use of the built–in Scheme objects printer. Return the old
printer function or #f
if no printer function was set for this
std.
Return #f
or a function previously set as custom struct printer
for instances of struct type std. When the return value is
#f
: instances of type std make use of the built–in Scheme
objects printer.
Next: syslib structs safe final, Previous: syslib structs safe inspect, Up: syslib structs safe [Index]