% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/altSaveObject.R
\name{altSaveObject}
\alias{altSaveObject}
\alias{.stageObject}
\alias{.altStageObject}
\alias{altStageObject}
\alias{altStageObjectFunction}
\alias{altSaveObjectFunction}
\title{Alter the saving generic}
\usage{
altSaveObject(x, path, ...)

altSaveObjectFunction(generic)
}
\arguments{
\item{x, path, ...}{Further arguments to pass to \code{\link{saveObject}} or an equivalent generic.}

\item{generic}{Generic function that can serve as a drop-in replacement for \code{\link{saveObject}}.}
}
\value{
For \code{altSaveObject}, files are created at the specified location, see \code{\link{saveObject}} for details.

For \code{altSaveObjectFunction}, the alternative generic (if any) is returned if \code{generic} is missing.
If \code{generic} is provided, it is used to define the alternative, and the previous alternative is returned.
}
\description{
Allow alabaster applications to divert to a different saving generic instead of \code{\link{saveObject}}.
}
\details{
By default, \code{altSaveObject} is just a wrapper around \code{\link{saveObject}}.
However, if \code{altSaveObjectFunction} is called, \code{altSaveObject} calls the replacement \code{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 \code{altSaveObject} to save child objects when implementing \code{saveObject} methods,
to ensure that application-specific customizations are respected for the children.

To motivate the use of \code{altSaveObject}, consider the following scenario.
\enumerate{
\item We have created a staging method for class X, defined for the \code{\link{saveObject}} generic.
\item An alabaster application Y requires the addition of some custom metadata during the staging process for X.
It defines an alternative staging generic \code{saveObject2} that, upon encountering an instance of X, redirects to an application-specific method (i.e., \code{saveObject2,X-method}).
For example, the \code{saveObject2} method for X could call X's \code{saveObject} method and add the necessary metadata to the result.
\item When operating in the context of application Y, the \code{saveObject2} generic is used to set \code{altSaveObjectFunction}.
Any calls to \code{altSaveObject} in Y's context will subsequently call \code{saveObject2}.
\item So, when writing a \code{saveObject} method for any objects that might contain an instance of X as a child, 
we call \code{\link{altSaveObject}} on that X object instead of directly using \code{\link{saveObject}}. 
This ensures that, if a child instance of X is encountered \emph{and} we are operating in the context of application Y, 
we correctly call \code{saveObject2} and then ultimately the application-specific method.
}

The application-specific \code{generic} is free to do anything it wants as long as the custom representation is understood by the application-specific reader in \code{\link{altReadObject}}.
However, it is usually most convenient to re-use the existing representations created by \code{\link{saveObject}}.
This means that any customizations should not interfere with the validity of those representations, as defined by the \pkg{takane} specifications and enforced by \code{\link{validateObject}}.
We recommend that any customizations should manifest as new files starting with an underscore, as this will not interfere by any \pkg{takane} file specification.
}
\examples{
old <- altSaveObjectFunction()

# Creating a new generic for demonstration purposes:
setGeneric("superSaveObject", function(x, path, ...)
    standardGeneric("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)

# Restoring the old loader:
altSaveObjectFunction(old)

}
\author{
Aaron Lun
}
