% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/misc.utilities.R
\name{once}
\alias{once}
\title{Evaluate a function once for a given input.}
\usage{
once(f, expire_after = Inf, max_entries = Inf)
}
\arguments{
\item{f}{A function to modify.}

\item{expire_after}{The number of seconds since it was added to the
database before a particular configuration is "forgotten". This
can be used to periodically remind the user without overwhelming
them.}

\item{max_entries}{The number of distinct configurations to
remember. If not \code{Inf}, \emph{earliest-inserted} configurations will
be removed from the database when capacity is exceeded. (This
exact behavior may change in the future.)}
}
\description{
This is a \code{purrr}-style adverb that checks if a given function has
already been called with a given configuration of arguments and
skips it if it has.
}
\details{
Each modified function instance returned by \code{once()}
maintains a database of previous argument configurations. They
are not in any way compressed, so this database may grow over
time. Thus, this wrapper should be used with caution if arguments
are large objects. This may be replaced with hashing in the
future. In the meantime, you may want to set the \code{max_entries}
argument to be safe.

Different instances of a modified function do not share
databases, even if the function is the same. This means that if
you, say, modify a function within another function, the modified
function will call once per call to the outer function. Modified
functions defined at package level count as the same "instance",
however. See example.
}
\note{
Because the function needs to test whether a particular
configuration of arguments have already been used, do not rely on
lazy evaluation behaviour.
}
\examples{
msg <- once(message)
msg("abc") # Prints.
msg("abc") # Silent.

msg <- once(message) # Starts over.
msg("abc") # Prints.

f <- function(){
  innermsg  <- once(message)
  innermsg("efg") # Prints once per call to f().
  innermsg("efg") # Silent.
  msg("abcd") # Prints only the first time f() is called.
  msg("abcd") # Silent.
}
f() # Prints "efg" and "abcd".
f() # Prints only "efg".

msg3 <- once(message, max_entries=3)
msg3("a") # 1 remembered.
msg3("a") # Silent.
msg3("b") # 2 remembered.
msg3("a") # Silent.
msg3("c") # 3 remembered.
msg3("a") # Silent.
msg3("d") # "a" forgotten.
msg3("a") # Printed.

msg2s <- once(message, expire_after=2)
msg2s("abc") # Prints.
msg2s("abc") # Silent.
Sys.sleep(1)
msg2s("abc") # Silent after 1 sec.
Sys.sleep(1.1)
msg2s("abc") # Prints after 2.1 sec.

}
