Skip to contents

Most classes need nothing here: an S3, S4 or S7 object is a base type plus attributes, so json_write() records it without help. A class whose instances hold something outside that model — a connection opened by initialize, a handle to a running process, a reference that has to be recorded as a key rather than a value — supplies a method for this pair instead, modeled on the __getstate__ and __setstate__ protocol of Python's pickle.

Usage

json_state(x)

json_revive(class, state)

Arguments

x

Object whose state is to be recorded.

class

Empty object carrying the recorded class vector, which json_revive() dispatches on.

state

Whatever the matching json_state() method returned.

Value

The json_state() function returns a list, and json_revive() the rebuilt object.

Details

A json_state() method returns a plain list of what to persist, and is free to leave out anything that can be recomputed. The document records that list next to the classes the object dispatches on, which for an S4 object or a reference class instance is its inheritance chain rather than the concrete class alone. On the way back, json_revive() dispatches on the recorded classes through an empty object carrying them, so a method signature always starts with the class token rather than the object being rebuilt, and a method registered on a superclass is reached both ways.

Methods for the class generators of both R6 and S7 ship with the package and follow the same protocol. An R6 instance has no method, and writing one is refused rather than guessed at; see r6_state() for why, and for the pair a class author opts in with. A reference class instance is refused on the same grounds. A method on the concrete class settles it, as does one on any class between that and envRefClass, which is where the refusal itself sits. The generator that makes one is refused outright, since a walk into it reaches the internals of the methods package rather than the class.

Examples

handle <- structure(list(path = "/tmp/log", con = "a live connection"),
                    class = "file_handle")

json_state.file_handle <- function(x) list(path = x$path)

json_revive.file_handle <- function(class, state) {
  structure(list(path = state$path, con = NULL), class = "file_handle")
}

json_write_str(handle)
#> [1] "{\"~a\":{\"class\":\"file_handle\"},\"~v\":{\"path\":\"/tmp/log\",\"con\":\"a live connection\"}}"

json_read_str(json_write_str(handle))
#> $path
#> [1] "/tmp/log"
#> 
#> $con
#> [1] "a live connection"
#> 
#> attr(,"class")
#> [1] "file_handle"