% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/encapsulate.R
\name{encapsulate}
\alias{encapsulate}
\title{Encapsulate Function Calls}
\usage{
encapsulate(
  method,
  .f,
  .args = list(),
  .opts = list(),
  .pkgs = character(),
  .seed = NA_integer_,
  .timeout = Inf,
  .compute = "default"
)
}
\arguments{
\item{method}{(\code{character(1)})\cr
One of \code{"none"}, \code{"try"}, \code{"evaluate"}, \code{"callr"}, or \code{"mirai"}.}

\item{.f}{(\verb{function()})\cr
Function to call.}

\item{.args}{(\code{list()})\cr
Named list of arguments passed to \code{.f}.}

\item{.opts}{(named \code{list()})\cr
Options to set via \code{\link[=options]{options()}} before calling \code{.f}. Restored on exit.}

\item{.pkgs}{(\code{character()})\cr
Packages to load via \code{\link[=requireNamespace]{requireNamespace()}} before calling \code{.f}.}

\item{.seed}{(\code{integer(1)})\cr
Random seed set via \code{\link[=set.seed]{set.seed()}} before calling \code{.f}.
If \code{NA} (default), the seed is not changed; for \code{"callr"} and \code{"mirai"} modes the current RNG state is forwarded instead.}

\item{.timeout}{(\code{numeric(1)})\cr
Timeout in seconds (\code{Inf} for no limit).
Uses \code{\link[=setTimeLimit]{setTimeLimit()}} for \code{"none"} and \code{"evaluate"}; passed natively to \code{callr::r()} and \code{mirai::mirai()} for the other modes.}

\item{.compute}{(\code{character(1)})\cr
Compute profile for \code{"mirai"} mode. Passed to \code{mirai::mirai()} as \code{.compute}.}
}
\value{
Named \code{list()} with three elements:
\itemize{
\item \code{"result"}: return value of \code{.f}, or \code{NULL} if an error was caught.
\item \code{"elapsed"}: elapsed time in seconds, measured via \code{\link[=proc.time]{proc.time()}}.
\item \code{"log"}: \code{data.table()} with columns \code{"class"} (ordered factor with levels
\code{"output"}, \code{"warning"}, \code{"error"}) and \code{"condition"} (list of condition objects).
Messages are classified as \code{"output"} for historical reasons.
Empty when no conditions were captured.
}
}
\description{
Evaluates a function, capturing conditions and measuring elapsed time.
There are currently five modes:
\itemize{
\item \code{"none"}: Runs the call in the current session.
Conditions are signaled normally; no log is kept.
Works well together with \code{\link[=traceback]{traceback()}}.
\item \code{"try"}: Like \code{"none"}, but catches errors and writes them to the log.
Warnings and messages are still signaled.
\item \code{"evaluate"}: Uses \CRANpkg{evaluate} to capture errors, warnings, and messages into the log.
Printed output is lost.
\item \code{"callr"}: Uses \CRANpkg{callr} to run the function in a fresh R session.
Errors, warnings, and messages are captured into the log; printed output is lost.
Protects the calling session from segfaults at the cost of session startup overhead.
The RNG state is propagated back to the calling session after evaluation.
\item \code{"mirai"}: Uses \CRANpkg{mirai} to run the function on a daemon.
Errors, warnings, and messages are captured into the log; printed output is lost.
The daemon can be pre-started via \code{daemons(1)}; if none is running, a new session is started per call.
Offers similar safety to \code{"callr"} with lower overhead when a daemon is reused across calls.
The RNG state is propagated back to the calling session after evaluation.
}
}
\examples{
f = function(n) {
  message("hi from f")
  if (n > 5) {
    stop("n must be <= 5")
  }
  runif(n)
}

encapsulate("none", f, list(n = 1), .seed = 1)

if (requireNamespace("evaluate", quietly = TRUE)) {
  encapsulate("evaluate", f, list(n = 1), .seed = 1)
}

if (requireNamespace("callr", quietly = TRUE)) {
  encapsulate("callr", f, list(n = 1), .seed = 1)
}
}
