Skip to contents

[Stable]

Create a qenv object and evaluate code in it to track code history.

Usage

qenv()

new_qenv(env = new.env(parent = parent.env(.GlobalEnv)), code = character())

eval_code(object, code)

get_code(object, deparse = TRUE, ...)

# S3 method for qenv
within(data, expr, ...)

Arguments

env

[Deprecated] (environment) Environment being a result of the code evaluation.

code

(character or language) code to evaluate. If character, comments are retained.

object

(qenv)

deparse

(logical(1)) flag specifying whether to return code as character or expression.

...

see Details

data

(qenv)

expr

(expression) to evaluate. Must be inline code, see Using language objects...

Value

qenv and new_qenv return a qenv object.

eval_code returns a qenv object with expr evaluated or qenv.error if evaluation fails.

get_code returns the traced code (from @code slot) in the form specified by deparse.

within returns a qenv object with expr evaluated or qenv.error if evaluation fails.

Details

qenv() instantiates a qenv with an empty environment. Any changes must be made by evaluating code in it with eval_code or within, thereby ensuring reproducibility.

new_qenv() ([Deprecated] and not recommended) can instantiate a qenv object with data in the environment and code registered.

eval_code evaluates given code in the qenv environment and appends it to the code slot. Thus, if the qenv had been instantiated empty, contents of the environment are always a result of the stored code.

get_code retrieves the code stored in the qenv. ... passes arguments to methods.

within is a convenience function for evaluating inline code inside the environment of a qenv. It is a method for the base generic that wraps eval_code to provide a simplified way of passing code. within accepts only inline expressions (both simple and compound) and allows for injecting values into expr through the ... argument: as name:value pairs are passed to ..., name in expr will be replaced with value.

Using language objects with within

Passing language objects to expr is generally not intended but can be achieved with do.call. Only single expressions will work and substitution is not available. See examples.

Examples

# create empty qenv
qenv()
#> <environment: 0x55ddf6fa1b50> [L]
#> Parent: <environment: devtools_shims>

# create qenv with data and code (deprecated)
new_qenv(env = list2env(list(a = 1)), code = quote(a <- 1))
#> Warning: `new_qenv()` was deprecated in teal.code 0.5.0.
#>  Please use `qenv()` instead.
#> <environment: 0x55ddf429c1f8> [L]
#> Parent: <environment: devtools_shims>
#> Bindings:
#>  a: <dbl> [L]
new_qenv(env = list2env(list(a = 1)), code = parse(text = "a <- 1", keep.source = TRUE))
#> Warning: `new_qenv()` was deprecated in teal.code 0.5.0.
#>  Please use `qenv()` instead.
#> <environment: 0x55ddf7102b38> [L]
#> Parent: <environment: devtools_shims>
#> Bindings:
#>  a: <dbl> [L]
new_qenv(env = list2env(list(a = 1)), code = "a <- 1")
#> Warning: `new_qenv()` was deprecated in teal.code 0.5.0.
#>  Please use `qenv()` instead.
#> <environment: 0x55ddf8caf040> [L]
#> Parent: <environment: devtools_shims>
#> Bindings:
#>  a: <dbl> [L]

# evaluate code in qenv
q <- qenv()
q <- eval_code(q, "a <- 1")
q <- eval_code(q, quote(library(checkmate)))
q <- eval_code(q, expression(assert_number(a)))

# retrieve code
get_code(q)
#> [1] "a <- 1\nlibrary(checkmate)\nassert_number(a)"
get_code(q, deparse = FALSE)
#> expression({
#> a <- 1
#> library(checkmate)
#> assert_number(a)
#> })

# evaluate code using within
q <- qenv()
q <- within(q, {
  i <- iris
})
q <- within(q, {
  m <- mtcars
  f <- faithful
})
q
#> <environment: 0x55ddf7f30cd8> [L]
#> Parent: <environment: package:checkmate>
#> Bindings:
#>  f: <df[,2]> [L]
#>  i: <df[,5]> [L]
#>  m: <df[,11]> [L]
get_code(q)
#> [1] "i <- iris\nm <- mtcars\nf <- faithful"

# inject values into code
q <- qenv()
q <- within(q, i <- iris)
within(q, print(dim(subset(i, Species == "virginica"))))
#> [1] 50  5
#> <environment: 0x55ddf76b3c18> [L]
#> Parent: <environment: package:checkmate>
#> Bindings:
#>  i: <df[,5]> [L]
within(q, print(dim(subset(i, Species == species)))) # fails
#> <qenv.error: object 'species' not found 
#>  when evaluating qenv code:
#> print(dim(subset(i, Species == species)))>
within(q, print(dim(subset(i, Species == species))), species = "versicolor")
#> [1] 50  5
#> <environment: 0x55ddf6f2bce8> [L]
#> Parent: <environment: package:checkmate>
#> Bindings:
#>  i: <df[,5]> [L]
species_external <- "versicolor"
within(q, print(dim(subset(i, Species == species))), species = species_external)
#> [1] 50  5
#> <environment: 0x55ddf4856238> [L]
#> Parent: <environment: package:checkmate>
#> Bindings:
#>  i: <df[,5]> [L]

# pass language objects
expr <- expression(i <- iris, m <- mtcars)
within(q, expr) # fails
#> <qenv.error: object 'expr' not found 
#>  when evaluating qenv code:
#> expr>
do.call(within, list(q, expr))
#> <environment: 0x55ddfa5d08f8> [L]
#> Parent: <environment: package:checkmate>
#> Bindings:
#>  i: <df[,5]> [L]
#>  m: <df[,11]> [L]

exprlist <- list(expression(i <- iris), expression(m <- mtcars))
within(q, exprlist) # fails
#> <qenv.error: object 'exprlist' not found 
#>  when evaluating qenv code:
#> exprlist>
do.call(within, list(q, do.call(c, exprlist)))
#> <environment: 0x55ddfa9589d0> [L]
#> Parent: <environment: package:checkmate>
#> Bindings:
#>  i: <df[,5]> [L]
#>  m: <df[,11]> [L]