Useful to represent functions efficiently within repr().

crate_env(fun, namespace = "R_GlobalEnv", ..., selfref = NULL)

Arguments

fun

(function)
Function of which the environment should be set.

namespace

(character(1))
Name of the namespace, as given by environmentName(), to be used as the (parent of the) environment of fun. Special values "R_GlobalEnv" (global environment), "R_BaseEnv" (base environment; note this one is non-standard within R), "R_EmptyEnv" (empty environment). The content of the namespace is not modified. Default "R_GlobalEnv".

...

(list)
Content of environments within which to place fun.

selfref

(character(1) | named integer | NULL)
If character(1): The name of the entry of the first element in ... that refers to the function itself. If a named integer, then the values indicate the lists in ... where the reference to the function should be placed see examples. Default NULL: No reference to the function itself is present.

Value

function: The given fun with changed environment.

Examples


identity2 = crate_env(function(x) x, "base")
identical(identity, identity2)  # TRUE
#> [1] TRUE

y = 1
f1 = mlr3misc::crate(function(x) x + y, y, .parent = .GlobalEnv)
f2 = crate_env(function(x) x + y, "R_GlobalEnv", list(y = 1))

# Note identical() does not apply because both contain (equal, but not
# identical) 'y = 1'-environments
all.equal(f1, f2)  # TRUE
#> [1] TRUE
f1(10)  # 10 + 1 == 11
#> [1] 11

factorial1 = mlr3misc::crate(
  function(x) if (x > 0) x * factorial1(x - 1) else 1,
  y, .parent = .GlobalEnv
)
environment(factorial1)$factorial1 = factorial1

factorial2 = crate_env(
  function(x) if (x > 0) x * factorial1(x - 1) else 1,
  "R_GlobalEnv", list(y = 1), selfref = "factorial1")
# putting 'factorial1' into the list (or repeating function(x) ....)
# would *not* work, since we want:
identical(environment(factorial2)$factorial1, factorial2)  # TRUE
#> [1] TRUE

all.equal(factorial1, factorial2)  # TRUE
#> [1] TRUE

g = crate_env(function(x) x + y + z, "miesmuschel",
  list(y = 1), list(z = 2), selfref = c(X = 1, Y = 2, Z = 2))
g(0)  # 0 + 1 + 2 == 3
#> [1] 3
identical(environment(g)$X, g)
#> [1] TRUE
identical(parent.env(environment(g))$Y, g)
#> [1] TRUE
identical(parent.env(environment(g))$Z, g)
#> [1] TRUE
identical(
  parent.env(parent.env(environment(g))),
  loadNamespace("miesmuschel")
)
#> [1] TRUE