Read an object from its on-disk representation.
This is done by dispatching to an appropriate loading function based on the type in the OBJECT
file.
readObject(path, metadata = NULL, ...)
readObjectFunctionRegistry()
registerReadObjectFunction(type, fun, existing = c("old", "new", "error"))
String containing a path to a directory, itself created with a saveObject
method.
Named list containing metadata for the object - most importantly, the type
field that controls dispatch to the correct loading function.
If NULL
, this is automatically read by readObjectFile(path)
.
Further arguments to pass to individual methods.
String specifying the name of type of the object.
A loading function that accepts path
, metadata
and ...
(in that order), and returns the associated object.
This may also be NULL
to delete an existing entry in the registry.
Logical scalar indicating the action to take if a function has already been registered for type
-
keep the old or new function, or throw an error.
For readObject
, an object created from the on-disk representation in path
.
For readObjectFunctionRegistry
, a named list of functions used to load each object type.
For registerReadObjectFunction
, the function is added to the registry.
Application developers can override readObject
by specifying a custom function in altReadObject
.
This can be used to point to a different registry of reading functions, to perform pre- or post-reading actions, etc.
If customization is type-specific, the custom altReadObject
function can read the type from the OBJECT
file to determine the most appropriate course of action;
the OBJECT
metadata can then be passed to the metadata
argument of any internal readObject
calls to avoid a redundant read from the same file.
library(S4Vectors)
df <- DataFrame(A=1:10, B=LETTERS[1:10])
tmp <- tempfile()
saveObject(df, tmp)
readObject(tmp)
#> DataFrame with 10 rows and 2 columns
#> A B
#> <integer> <character>
#> 1 1 A
#> 2 2 B
#> 3 3 C
#> 4 4 D
#> 5 5 E
#> 6 6 F
#> 7 7 G
#> 8 8 H
#> 9 9 I
#> 10 10 J
Comments for extension developers
readObject
uses an internal registry of functions to decide how an object should be loaded into memory. Developers of alabaster extensions can add extra functions to this registry, usually in the.onLoad
function of their packages. Alternatively, extension developers can request the addition of their packages to default registry.If a loading function makes use of additional arguments in
...
, those arguments should be prefixed by the name of the object type for each method, e.g.,simple_list.parallel
. This avoids problems with conflicts in the interpretation of identically named arguments between different functions. Unlike the...
arguments insaveObject
, we prefix by the object type instead of the output class, as the former is used for dispatch here.When writing loading functions for complex classes, extension developers may need to load child objects to compose the output object. In such cases, developers should use
altReadObject
on the child subdirectories, rather than callingreadObject
directly. This ensures that any application-level overrides of the loading functions are respected. It is also expected that arguments in...
are forwarded to internalaltReadObject
calls.Developers can manually control
readObject
dispatch by suppling ametadata
list wheremetadata$type
is set to the desired object type. This pattern is commonly used inside the loading function for a subclass - an instance of the base class is first constructed by an internalreadObject
call with the modifiedmetadata$type
, after which the subclass-specific slots are added. (In practice, base construction should be done usingaltReadObject
so as to respect application-specific overrides.)