
Last chance! 50% off unlimited learning
Sale ends in
These functions create bindings in an environment. The bindings are
supplied through ...
as pairs of names and values or expressions.
env_bind()
is equivalent to evaluating a <-
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.
env_bind()
takes named values. The arguments are evaluated
once (with explicit splicing) and bound in .env
.
env_bind()
is equivalent to base::assign()
.
env_bind_fns()
takes named functions and creates active
bindings in .env
. This is equivalent to
base::makeActiveBinding()
. An active binding executes a
function each time it is evaluated. env_bind_fns()
takes dots
with implicit splicing, so that you can supply
both named functions and named lists of functions.
If these functions are closures they are lexically
scoped in the environment that they bundle. 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 dplyr::do()
methods for an
example).
env_bind_exprs()
takes named expressions. This is equivalent
to base::delayedAssign()
. The arguments are captured with
exprs()
(and thus support call-splicing and unquoting) and
assigned to symbols in .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).
env_bind(.env, ...)env_bind_exprs(.env, ..., .eval_env = caller_env())
env_bind_fns(.env, ...)
Pairs of names and expressions, values or functions. These dots support splicing (with varying semantics, see above) and name unquoting.
The environment where the expressions will be evaluated when the symbols are forced.
The input object .env
, with its associated environment
modified in place, invisibly.
Since environments have reference semantics (see relevant section
in env()
documentation), modifying the bindings of an environment
produces effects in all other references to that environment. In
other words, env_bind()
and its variants have side effects.
As they are called primarily for their side effects, these functions follow the convention of returning their input invisibly.
# NOT RUN {
# env_bind() is a programmatic way of assigning values to symbols
# with `<-`. We can add bindings in the current environment:
env_bind(get_env(), foo = "bar")
foo
# Or modify those bindings:
bar <- "bar"
env_bind(get_env(), bar = "BAR")
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
# env_bind() and its variants are generic over formulas, quosures
# and closures. To illustrate this, let's create a closure function
# referring to undefined bindings:
fn <- function() list(a, b)
fn <- set_env(fn, child_env("base"))
# This would fail if run since `a` etc are not defined in the
# enclosure of fn() (a child of the base environment):
# fn()
# Let's define those symbols:
env_bind(fn, a = "a", b = "b")
# fn() now sees the objects:
fn()
# env_bind_exprs() assigns expressions lazily:
env <- env()
env_bind_exprs(env, name = cat("forced!\n"))
env$name
env$name
# You can unquote expressions. Note that quosures are not
# supported, only raw expressions:
expr <- quote(message("forced!"))
env_bind_exprs(env, name = !! expr)
env$name
# You can create active bindings with env_bind_fns()
# Let's create some bindings in the lexical enclosure of `fn`:
counter <- 0
# And now a function that increments the counter and returns a
# string with the count:
fn <- function() {
counter <<- counter + 1
paste("my counter:", counter)
}
# Now we create an active binding in a child of the current
# environment:
env <- env()
env_bind_fns(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)
# }
Run the code above in your browser using DataLab