How to print Racket structs
Asked Answered
G

2

6

Is there any way to control how a struct is printed?

For example if I have a transparent struct containing an image:

(struct photo (label image-data) #:transparent)

But I don't want to print the image-data field.

Giroux answered 20/9, 2016 at 19:22 Comment(0)
V
8

I want to extend Ben's answer a bit. You can also combine gen:custom-write with make-constructor-style-printer to make the struct printing significantly easier. This function handles the differences between printing, writing, quote depth, and output port for you.

Extending his example gives:

#lang racket
(require pict
         racket/struct)

(struct photo (label image-data)
  #:transparent
  #:methods gen:custom-write
  [(define write-proc
     (make-constructor-style-printer
       (lambda (obj) 'photo)
       (lambda (obj) (list (photo-label obj)))))])

(displayln (photo "fish" (standard-fish 100 100)))
;; Prints #<photo: fish>

(println (photo "fish" (standard-fish 100 100)))
;; Prints (photo "fish")

Now write, display, and print all work as you would expect

Venetic answered 20/9, 2016 at 21:9 Comment(0)
G
8

Yes! Use the gen:custom-write generic interface.

#lang racket
(require pict)

(struct photo (label image-data)
  #:transparent
  #:methods gen:custom-write
  [(define (write-proc photo-val output-port output-mode)
     (fprintf output-port "#<photo:~a>" (photo-label photo-val)))])

(photo "fish" (standard-fish 100 100))
;; Prints "#<photo:fish>"

The first argument to write-proc is the struct to be printed. The second argument is the port to print to. The third argument suggests how the context wants the value printed, see the docs: http://docs.racket-lang.org/reference/Printer_Extension.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._gen~3acustom-write%29%29

Giroux answered 20/9, 2016 at 19:22 Comment(0)
V
8

I want to extend Ben's answer a bit. You can also combine gen:custom-write with make-constructor-style-printer to make the struct printing significantly easier. This function handles the differences between printing, writing, quote depth, and output port for you.

Extending his example gives:

#lang racket
(require pict
         racket/struct)

(struct photo (label image-data)
  #:transparent
  #:methods gen:custom-write
  [(define write-proc
     (make-constructor-style-printer
       (lambda (obj) 'photo)
       (lambda (obj) (list (photo-label obj)))))])

(displayln (photo "fish" (standard-fish 100 100)))
;; Prints #<photo: fish>

(println (photo "fish" (standard-fish 100 100)))
;; Prints (photo "fish")

Now write, display, and print all work as you would expect

Venetic answered 20/9, 2016 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.