[plt-scheme] serialization: transient fields

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Aug 12 07:58:41 EDT 2006

At Wed, 09 Aug 2006 22:49:56 -0400, Jon Rafkind wrote:
> I quickly realized this doesnt work with deserialization. The exact
> problem, if it isn't obvious, seems to be the class body is never
> evaluated and so any constructors or definitions are not called when the
> object is deserialized.

It's certainly true that constructors are not called by deserialization
(except for instances of externalizable<%>, in which case the
constructor is always called with no initialization arguments).

I'm pretty sure that `define/transient' works like `transient' in Java.
Maybe you want to perform some work at deserialization time to restore
values in transient fields?

> I tried changing the transient definition so
> that the internalize method would always create the transient class with
> the proper value, that value passed as v to (define t-id v).
>   (define-serializable-class* transient% object% (externalizable<%>)
>     (init-field [val #f] [create-thunk (lambda () (void))])
>     (define/public (externalize) #f)
>     (define/public (internalize v) (create-thunk))
>     (super-new))

The `internalize' method is called on an object instantiated with no
initialization arguments. Thus, `create-thunk' above lways has its
default value when called via `internalize'.

Any information that you want to communicate from serialization to
deserialization must be in the result from `externalize', and then used
via the argument to `internalize'. Also, the result from `externalize'
must be serializable.

So, you can create a variant of `transient%' that keeps an object
reference instead of a closure. The `externalize' method could return
that reference instead of #f. Finally, the `internalize' method could
use the object, supplied as `v', to re-initialize `val'.

  (define-serializable-class* transient% object% (externalizable<%>)
    (init-field [val #f] [restorer #f])
    (define/public (externalize) restorer)
    (define/public (internalize v)
      (set! restorer v)
      (set! val (send restorer restore-value)))


Posted on the users mailing list.