env_bind {rlang}R Documentation

Bind symbols to objects in an environment

Description

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.

Usage

env_bind(.env, ...)

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

env_bind_fns(.env, ...)

Arguments

.env

An environment or an object bundling an environment, e.g. a formula, quosure or closure. This argument is passed to get_env().

...

Pairs of names and expressions, values or functions. These dots support splicing (with varying semantics, see above) and name unquoting.

.eval_env

The environment where the expressions will be evaluated when the symbols are forced.

Value

The input object .env, with its associated environment modified in place, invisibly.

Side effects

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.

Examples

# 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)

[Package rlang version 0.1.6 Index]