I am trying to customize the printing of a struct for the display case to something that displays more user-friendly but I am not sure how to express: "do the default action for print and write cases".
Here is the code I have:
(define (service-print service port mode)
(case mode
; WRITE-mode - I want to use the default printer behaviour
[(#t)
(write service port)]
; DISPLAY-mode - Use my custom behaviour
[(#f)
(fprintf port "#<service ~a>" (service.-id service))]
; PRINT-mode - I want to use the default printer behaviour
[else
(print service port mode)]))
(struct service.
(id ; ^String
opts ; ^HashTable
)
#:methods gen:custom-write
[(define write-proc service-print)])
The code above gives the following strange result for the print and write cases:
Racket does not provide a way to do that, I believe. There's not much point, since the default would be just
(fprintf port "#<service>")
If you actually want to print more information, you could also have your printer fall back to a printer constructed using make-constructor-style-printer for some cases.
That's how Racket prints cyclic data structures. For example, here's a cyclic "list" of ones:
The #0= means "label the next value I print with the 0", and the #0# means "this is a reference back to the enclosing value labeled with 0"
When Racket prints a service object s, the Racket printer makes a note that it's currently printing s. When the custom printer for s calls write (or print) on s again, Racket detects the cycle and inserts the sharing notation. It's an abuse of the sharing notation (you can't read it, for example), but your printer is saying "To print me out, just print me out."
Maybe I should rethink my approach to this problem. I would like to display the
abbreviated values such as:
#<service Transport>
But changing the default printing behaviour by implementing gen:custom-write might not be what I should be doing. It does not feel like the right tool for the job?
I think I will try defining my own interface for my structs that are specifically used for the purpose of displaying abbreviated values and traversing child values of the graph.
Thanks for explaining the sharing notation. I will read up about that topic a bit more.