% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/env-binding.R
\name{env_bind}
\alias{env_bind}
\alias{env_bind_lazy}
\alias{env_bind_active}
\alias{\%<~\%}
\title{Bind symbols to objects in an environment}
\usage{
env_bind(.env, ...)

env_bind_lazy(.env, ..., .eval_env = caller_env())

env_bind_active(.env, ...)

lhs \%<~\% rhs
}
\arguments{
\item{.env}{An environment.}

\item{...}{<\link[=dyn-dots]{dynamic}> Named objects (\code{env_bind()}),
expressions \code{env_bind_lazy()}, or functions (\code{env_bind_active()}).
Use \code{\link[=zap]{zap()}} to remove bindings.}

\item{.eval_env}{The environment where the expressions will be
evaluated when the symbols are forced.}

\item{lhs}{The variable name to which \code{rhs} will be lazily assigned.}

\item{rhs}{An expression lazily evaluated and assigned to \code{lhs}.}
}
\value{
The input object \code{.env}, with its associated environment
modified in place, invisibly.
}
\description{
These functions create bindings in an environment. The bindings are
supplied through \code{...} as pairs of names and values or expressions.
\code{env_bind()} is equivalent to evaluating a \verb{<-} expression within
the given environment. This function should take care of the
majority of use cases but the other variants can be useful for
specific problems.
\itemize{
\item \code{env_bind()} takes named \emph{values} which are bound in \code{.env}.
\code{env_bind()} is equivalent to \code{\link[base:assign]{base::assign()}}.
\item \code{env_bind_active()} takes named \emph{functions} and creates active
bindings in \code{.env}. This is equivalent to
\code{\link[base:bindenv]{base::makeActiveBinding()}}. An active binding executes a
function each time it is evaluated. The arguments are passed to
\code{\link[=as_function]{as_function()}} so you can supply formulas instead of functions.

Remember that functions are scoped in their own environment.
These functions can thus refer to symbols from this enclosure
that are not actually in scope in the dynamic environment where
the active bindings are invoked. This allows creative solutions
to difficult problems (see the implementations of \code{dplyr::do()}
methods for an example).
\item \code{env_bind_lazy()} takes named \emph{expressions}. This is equivalent
to \code{\link[base:delayedAssign]{base::delayedAssign()}}. The arguments are captured with
\code{\link[=exprs]{exprs()}} (and thus support call-splicing and unquoting) and
assigned to symbols in \code{.env}. These expressions are not
evaluated immediately but lazily. Once a symbol is evaluated, the
corresponding expression is evaluated in turn and its value is
bound to the symbol (the expressions are thus evaluated only
once, if at all).
\item \verb{\%<~\%} is a shortcut for \code{env_bind_lazy()}. It works like \verb{<-}
but the RHS is evaluated lazily.
}
}
\section{Side effects}{


Since environments have reference semantics (see relevant section
in \code{\link[=env]{env()}} documentation), modifying the bindings of an environment
produces effects in all other references to that environment. In
other words, \code{env_bind()} and its variants have side effects.

Like other side-effecty functions like \code{par()} and \code{options()},
\code{env_bind()} and variants return the old values invisibly.
}

\examples{
# env_bind() is a programmatic way of assigning values to symbols
# with `<-`. We can add bindings in the current environment:
env_bind(current_env(), foo = "bar")
foo

# Or modify those bindings:
bar <- "bar"
env_bind(current_env(), bar = "BAR")
bar

# You can remove bindings by supplying zap sentinels:
env_bind(current_env(), foo = zap())
try(foo)

# Unquote-splice a named list of zaps
zaps <- rep_named(c("foo", "bar"), list(zap()))
env_bind(current_env(), !!!zaps)
try(bar)

# It is most useful to change other environments:
my_env <- env()
env_bind(my_env, foo = "foo")
my_env$foo

# A useful feature is to splice lists of named values:
vals <- list(a = 10, b = 20)
env_bind(my_env, !!!vals, c = 30)
my_env$b
my_env$c

# You can also unquote a variable referring to a symbol or a string
# as binding name:
var <- "baz"
env_bind(my_env, !!var := "BAZ")
my_env$baz


# The old values of the bindings are returned invisibly:
old <- env_bind(my_env, a = 1, b = 2, baz = "baz")
old

# You can restore the original environment state by supplying the
# old values back:
env_bind(my_env, !!!old)

# env_bind_lazy() assigns expressions lazily:
env <- env()
env_bind_lazy(env, name = { cat("forced!\n"); "value" })

# Referring to the binding will cause evaluation:
env$name

# But only once, subsequent references yield the final value:
env$name

# You can unquote expressions:
expr <- quote(message("forced!"))
env_bind_lazy(env, name = !!expr)
env$name


# By default the expressions are evaluated in the current
# environment. For instance we can create a local binding and refer
# to it, even though the variable is bound in a different
# environment:
who <- "mickey"
env_bind_lazy(env, name = paste(who, "mouse"))
env$name

# You can specify another evaluation environment with `.eval_env`:
eval_env <- env(who = "minnie")
env_bind_lazy(env, name = paste(who, "mouse"), .eval_env = eval_env)
env$name

# Or by unquoting a quosure:
quo <- local({
  who <- "fievel"
  quo(paste(who, "mouse"))
})
env_bind_lazy(env, name = !!quo)
env$name

# You can create active bindings with env_bind_active(). Active
# bindings execute a function each time they are evaluated:
fn <- function() {
  cat("I have been called\n")
  rnorm(1)
}

env <- env()
env_bind_active(env, symbol = fn)

# `fn` is executed each time `symbol` is evaluated or retrieved:
env$symbol
env$symbol
eval_bare(quote(symbol), env)
eval_bare(quote(symbol), env)

# All arguments are passed to as_function() so you can use the
# formula shortcut:
env_bind_active(env, foo = ~ runif(1))
env$foo
env$foo
}
\seealso{
\code{\link[=env_poke]{env_poke()}} for binding a single element.
}
