Allow alabaster applications to divert to a different saving generic instead of saveObject
.
altSaveObject(x, path, ...)
altSaveObjectFunction(generic)
Further arguments to pass to saveObject
or an equivalent generic.
Generic function that can serve as a drop-in replacement for saveObject
.
For altSaveObject
, files are created at the specified location, see saveObject
for details.
For altSaveObjectFunction
, the alternative generic (if any) is returned if generic
is missing.
If generic
is provided, it is used to define the alternative, and the previous alternative is returned.
By default, altSaveObject
is just a wrapper around saveObject
.
However, if altSaveObjectFunction
is called, altSaveObject
calls the replacement generic
instead.
This allows alabaster applications to inject wholesale or class-specific customizations into the saving process,
e.g., to save more metadata whenever an instance of a particular class is encountered.
Developers of alabaster extensions should use altSaveObject
to save child objects when implementing saveObject
methods,
to ensure that application-specific customizations are respected for the children.
To motivate the use of altSaveObject
, consider the following scenario.
We have created a staging method for class X, defined for the saveObject
generic.
An alabaster application Y requires the addition of some custom metadata during the staging process for X.
It defines an alternative staging generic saveObject2
that, upon encountering an instance of X, redirects to an application-specific method (i.e., saveObject2,X-method
).
For example, the saveObject2
method for X could call X's saveObject
method and add the necessary metadata to the result.
When operating in the context of application Y, the saveObject2
generic is used to set altSaveObjectFunction
.
Any calls to altSaveObject
in Y's context will subsequently call saveObject2
.
So, when writing a saveObject
method for any objects that might contain an instance of X as a child,
we call altSaveObject
on that X object instead of directly using saveObject
.
This ensures that, if a child instance of X is encountered and we are operating in the context of application Y,
we correctly call saveObject2
and then ultimately the application-specific method.
The application-specific generic
is free to do anything it wants as long as the custom representation is understood by the application-specific reader in altReadObject
.
However, it is usually most convenient to re-use the existing representations created by saveObject
.
This means that any customizations should not interfere with the validity of those representations, as defined by the takane specifications and enforced by validateObject
.
We recommend that any customizations should manifest as new files starting with an underscore, as this will not interfere by any takane file specification.
old <- altSaveObjectFunction()
# Creating a new generic for demonstration purposes:
setGeneric("superSaveObject", function(x, path, ...)
standardGeneric("superSaveObject"))
#> [1] "superSaveObject"
setMethod("superSaveObject", "ANY", function(x, path, ...) {
print("Falling back to the base method!")
saveObject(x, path, ...)
})
altSaveObjectFunction(superSaveObject)
# Staging an example DataFrame. This should print our message.
library(S4Vectors)
df <- DataFrame(A=1:10, B=LETTERS[1:10])
tmp <- tempfile()
altSaveObject(df, tmp)
#> [1] "Falling back to the base method!"
# Restoring the old loader:
altSaveObjectFunction(old)