问题
I am looking for the canonical way to specify custom methods to output the fields of a Racket object. In other words I'm looking for the Racket equivalent of Java's toString method (if it exists).
I know that for structs one can use gen:custom-write to specify the write-proc function (source). Is there something similar for classes?
回答1:
Yes for custom-write. Since gen:custom-write is a wrapper around prop:custom-write, it is possible to have a class implement it through an interface.
The printable<%> interface implements prop:custom-write to allow things like this:
#lang racket
(define fish%
(class* object% (printable<%>)
(super-new)
(define/public (custom-print out depth)
(fprintf out "><,`>"))
(define/public (custom-write out)
(fprintf out "><,`>"))
(define/public (custom-display out)
(fprintf out "><,`>"))))
Using it:
> (new fish%)
><,`>
This is possible because the printable<%> interface uses the interface* form to inherit from the prop:custom-write struct-type property. However, this is not true for all generic interfaces, just the ones that correspond to struct-type-properties.
P.S. Don't worry too much about the documentation saying prop:custom-write is deprecated. It's just not necessary for "users" to use it, since gen:custom-write exists for structs and printable<%> exists for classes. It's deprecated as an interface, but as an implementation it is not going away. In that way it's "safe" to use without worrying.
来源:https://stackoverflow.com/questions/54844089/gencustom-write-for-racket-classes