eval_bare() is a lightweight version of the base function base::eval(). It does not accept supplementary data, but it is more efficient and does not clutter the evaluation stack. Technically, eval_bare() is a simple wrapper around the C function Rf_eval().

eval_bare(expr, env = parent.frame())

Arguments

expr

An expression to evaluate.

env

The environment in which to evaluate the expression.

Details

base::eval() inserts two call frames in the stack, the second of which features the envir parameter as frame environment. This may unnecessarily clutter the evaluation stack and it can change evaluation semantics with stack sensitive functions in the case where env is an evaluation environment of a stack frame (see ctxt_stack()). Since the base function eval() creates a new evaluation context with env as frame environment there are actually two contexts with the same evaluation environment on the stack when expr is evaluated. Thus, any command that looks up frames on the stack (stack sensitive functions) may find the parasite frame set up by eval() rather than the original frame targetted by env. As a result, code evaluated with base::eval() does not have the property of stack consistency, and stack sensitive functions like base::return(), base::parent.frame() may return misleading results.

See also

with_env

Examples

# eval_bare() works just like base::eval(): env <- child_env(NULL, foo = "bar") expr <- quote(foo) eval_bare(expr, env)
#> [1] "bar"
# To explore the consequences of stack inconsistent semantics, let's # create a function that evaluates `parent.frame()` deep in the call # stack, in an environment corresponding to a frame in the middle of # the stack. For consistency we R's lazy evaluation semantics, we'd # expect to get the caller of that frame as result: fn <- function(eval_fn) { list( returned_env = middle(eval_fn), actual_env = get_env() ) } middle <- function(eval_fn) { deep(eval_fn, get_env()) } deep <- function(eval_fn, eval_env) { expr <- quote(parent.frame()) eval_fn(expr, eval_env) } # With eval_bare(), we do get the expected environment: fn(rlang::eval_bare)
#> $returned_env #> <environment: 0x7f979d6354d8> #> #> $actual_env #> <environment: 0x7f979d6354d8> #>
# But that's not the case with base::eval(): fn(base::eval)
#> $returned_env #> <environment: 0x7f979d19a2a8> #> #> $actual_env #> <environment: 0x7f979d1b4040> #>
# Another difference of eval_bare() compared to base::eval() is # that it does not insert parasite frames in the evaluation stack: get_stack <- quote(identity(ctxt_stack())) eval_bare(get_stack)
#> [[1]] #> <frame 33> (31) #> expr: identity(ctxt_stack()) #> env: [local 0x7f979cd83ed0] #> #> [[2]] #> <frame 32> (31) #> expr: eval_bare(get_stack) #> env: [local 0x7f979cd83b88] #> #> [[3]] #> <frame 31> (30) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f97a0a64558] #> #> [[4]] #> <frame 30> (20) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f979cd838e8] #> #> [[5]] #> <frame 29> (20) #> expr: withVisible(eval(expr, envir, enclos)) #> env: [local 0x7f979bc745f0] #> #> [[6]] #> <frame 28> (20) #> expr: withCallingHandlers(withVisible(eval(expr, envir, enclos)), warning = wHandler, <...> #> env: [local 0x7f979bca96d0] #> #> [[7]] #> <frame 27> (26) #> expr: doTryCatch(return(expr), name, parentenv, handler) #> env: [local 0x7f979bca9078] #> #> [[8]] #> <frame 26> (25) #> expr: tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> env: [local 0x7f979bca9ca0] #> #> [[9]] #> <frame 25> (24) #> expr: tryCatchList(expr, classes, parentenv, handlers) #> env: [local 0x7f979bca9808] #> #> [[10]] #> <frame 24> (23) #> expr: tryCatch(expr, error = function(e) { <...> #> env: [local 0x7f979bcac3f8] #> #> [[11]] #> <frame 23> (22) #> expr: try(f, silent = TRUE) #> env: [local 0x7f979bcac200] #> #> [[12]] #> <frame 22> (20) #> expr: handle(ev <- withCallingHandlers(withVisible(eval(expr, envir, <...> #> env: [local 0x7f979bcad920] #> #> [[13]] #> <frame 21> (20) #> expr: timing_fn(handle(ev <- withCallingHandlers(withVisible(eval(expr, <...> #> env: [local 0x7f979bcad808] #> #> [[14]] #> <frame 20> (19) #> expr: evaluate_call(expr, parsed$src[[i]], envir = envir, enclos = enclos, <...> #> env: [frame 0x7f979d0b0990] #> #> [[15]] #> <frame 19> (18) #> expr: evaluate::evaluate(text, code_env, new_device = TRUE) #> env: [frame 0x7f97a0e94608] #> #> [[16]] #> <frame 18> (16) #> expr: as_data.tag_examples(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f979f7cd8a8] #> #> [[17]] #> <frame 17> (16) #> expr: as_data(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a08529f8] #> #> [[18]] #> <frame 16> (12) #> expr: data_reference_topic(topic, pkg, path = path, examples = examples, <...> #> env: [frame 0x7f979f24a4d0] #> #> [[19]] #> <frame 15> (14) #> expr: stopifnot(is.list(x), is.list(val)) #> env: [frame 0x7f97a0832950] #> #> [[20]] #> <frame 14> (13) #> expr: utils::modifyList(data, data_template(pkg, depth = depth)) #> env: [frame 0x7f97a0888898] #> #> [[21]] #> <frame 13> (12) #> expr: render_page(pkg, "reference-topic", data = data_reference_topic(topic, <...> #> env: [frame 0x7f979f3862e0] #> #> [[22]] #> <frame 12> (11) #> expr: .f(.x[[i]], ...) #> env: [frame 0x7f979f5e4510] #> #> [[23]] #> <frame 11> (10) #> expr: purrr::map(., build_reference_topic, path, pkg = pkg, lazy = lazy, <...> #> env: [frame 0x7f979cbee238] #> #> [[24]] #> <frame 10> (8) #> expr: function_list[[k]](value) #> env: [frame 0x7f97a0d3fd10] #> #> [[25]] #> <frame 9> (8) #> expr: withVisible(function_list[[k]](value)) #> env: [frame 0x7f97a0d3fdf0] #> #> [[26]] #> <frame 8> (7) #> expr: freduce(value, `_function_list`) #> env: [frame 0x7f979f468918] #> #> [[27]] #> <frame 7> (6) #> expr: `_fseq`(`_lhs`) #> env: [frame 0x7f979f468ad8] #> #> [[28]] #> <frame 6> (5) #> expr: eval(expr, envir, enclos) #> env: [frame 0x7f97a0936408] #> #> [[29]] #> <frame 5> (3) #> expr: eval(quote(`_fseq`(`_lhs`)), env, env) #> env: [frame 0x7f979f468c98] #> #> [[30]] #> <frame 4> (3) #> expr: withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) #> env: [frame 0x7f97a0e1ff20] #> #> [[31]] #> <frame 3> (2) #> expr: pkg$topics %>% purrr::transpose() %>% purrr::map(build_reference_topic, <...> #> env: [frame 0x7f97a09367c0] #> #> [[32]] #> <frame 2> (1) #> expr: build_reference(pkg, lazy = FALSE, examples = examples, run_dont_run = run_dont_run, <...> #> env: [frame 0x7f97a07138e8] #> #> [[33]] #> <frame 1> (0) #> expr: pkgdown::build_site("/Users/lionel/Dropbox/R/hadley/rlang") #> env: [frame 0x7f97a457e3c8] #> #> [[34]] #> <frame 0> [global] #> expr: NULL #> env: [global] #> #> attr(,"class") #> [1] "ctxt_stack" "stack"
eval(get_stack)
#> [[1]] #> <frame 34> (31) #> expr: identity(ctxt_stack()) #> env: [local 0x7f97a0fb7d48] #> #> [[2]] #> <frame 33> (32) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f97a0a64558] #> #> [[3]] #> <frame 32> (31) #> expr: eval(get_stack) #> env: [local 0x7f97a0988558] #> #> [[4]] #> <frame 31> (30) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f97a0a64558] #> #> [[5]] #> <frame 30> (20) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f97a0988788] #> #> [[6]] #> <frame 29> (20) #> expr: withVisible(eval(expr, envir, enclos)) #> env: [local 0x7f97a09889f0] #> #> [[7]] #> <frame 28> (20) #> expr: withCallingHandlers(withVisible(eval(expr, envir, enclos)), warning = wHandler, <...> #> env: [local 0x7f979f3fa430] #> #> [[8]] #> <frame 27> (26) #> expr: doTryCatch(return(expr), name, parentenv, handler) #> env: [local 0x7f979f121a38] #> #> [[9]] #> <frame 26> (25) #> expr: tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> env: [local 0x7f979f121d80] #> #> [[10]] #> <frame 25> (24) #> expr: tryCatchList(expr, classes, parentenv, handlers) #> env: [local 0x7f979f2c6920] #> #> [[11]] #> <frame 24> (23) #> expr: tryCatch(expr, error = function(e) { <...> #> env: [local 0x7f979f54d840] #> #> [[12]] #> <frame 23> (22) #> expr: try(f, silent = TRUE) #> env: [local 0x7f979f54da38] #> #> [[13]] #> <frame 22> (20) #> expr: handle(ev <- withCallingHandlers(withVisible(eval(expr, envir, <...> #> env: [local 0x7f979f54dbf8] #> #> [[14]] #> <frame 21> (20) #> expr: timing_fn(handle(ev <- withCallingHandlers(withVisible(eval(expr, <...> #> env: [local 0x7f979f54dd10] #> #> [[15]] #> <frame 20> (19) #> expr: evaluate_call(expr, parsed$src[[i]], envir = envir, enclos = enclos, <...> #> env: [frame 0x7f97a0eecad0] #> #> [[16]] #> <frame 19> (18) #> expr: evaluate::evaluate(text, code_env, new_device = TRUE) #> env: [frame 0x7f97a0e94608] #> #> [[17]] #> <frame 18> (16) #> expr: as_data.tag_examples(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f979f7cd8a8] #> #> [[18]] #> <frame 17> (16) #> expr: as_data(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a08529f8] #> #> [[19]] #> <frame 16> (12) #> expr: data_reference_topic(topic, pkg, path = path, examples = examples, <...> #> env: [frame 0x7f979f24a4d0] #> #> [[20]] #> <frame 15> (14) #> expr: stopifnot(is.list(x), is.list(val)) #> env: [frame 0x7f97a0832950] #> #> [[21]] #> <frame 14> (13) #> expr: utils::modifyList(data, data_template(pkg, depth = depth)) #> env: [frame 0x7f97a0888898] #> #> [[22]] #> <frame 13> (12) #> expr: render_page(pkg, "reference-topic", data = data_reference_topic(topic, <...> #> env: [frame 0x7f979f3862e0] #> #> [[23]] #> <frame 12> (11) #> expr: .f(.x[[i]], ...) #> env: [frame 0x7f979f5e4510] #> #> [[24]] #> <frame 11> (10) #> expr: purrr::map(., build_reference_topic, path, pkg = pkg, lazy = lazy, <...> #> env: [frame 0x7f979cbee238] #> #> [[25]] #> <frame 10> (8) #> expr: function_list[[k]](value) #> env: [frame 0x7f97a0d3fd10] #> #> [[26]] #> <frame 9> (8) #> expr: withVisible(function_list[[k]](value)) #> env: [frame 0x7f97a0d3fdf0] #> #> [[27]] #> <frame 8> (7) #> expr: freduce(value, `_function_list`) #> env: [frame 0x7f979f468918] #> #> [[28]] #> <frame 7> (6) #> expr: `_fseq`(`_lhs`) #> env: [frame 0x7f979f468ad8] #> #> [[29]] #> <frame 6> (5) #> expr: eval(expr, envir, enclos) #> env: [frame 0x7f97a0936408] #> #> [[30]] #> <frame 5> (3) #> expr: eval(quote(`_fseq`(`_lhs`)), env, env) #> env: [frame 0x7f979f468c98] #> #> [[31]] #> <frame 4> (3) #> expr: withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) #> env: [frame 0x7f97a0e1ff20] #> #> [[32]] #> <frame 3> (2) #> expr: pkg$topics %>% purrr::transpose() %>% purrr::map(build_reference_topic, <...> #> env: [frame 0x7f97a09367c0] #> #> [[33]] #> <frame 2> (1) #> expr: build_reference(pkg, lazy = FALSE, examples = examples, run_dont_run = run_dont_run, <...> #> env: [frame 0x7f97a07138e8] #> #> [[34]] #> <frame 1> (0) #> expr: pkgdown::build_site("/Users/lionel/Dropbox/R/hadley/rlang") #> env: [frame 0x7f97a457e3c8] #> #> [[35]] #> <frame 0> [global] #> expr: NULL #> env: [global] #> #> attr(,"class") #> [1] "ctxt_stack" "stack"