# The following example focuses on the difference between full and
# partial introspection of dots, which can be difficult to grasp.
h <- function(...) {
# Let's parameterise `only_dots` with a global variable
dots_inspect(..., .only_dots = only_dots)
}
g <- function(...) {
# Here dots are forwarded from g to h. The first node of `...` in
# h's frame environment is bound to a promise, pledging to evaluate
# `..1` in g's frame environment.
h(...)
}
f <- function(arg) {
# Here the first node of `...` in g's frame environment is bound to
# a promise, pledging to evaluate `arg` in f's frame environment.
g(arg)
}
# Here `arg` is bound to a promise, pledging to evaluate `foo(bar)`
# in the global environment. We request full
# introspection. Arguments are climbed beyond forwarded dots and
# introspection is given the same scope as lazy
# evaluation. dots_inspect() thus returns information about `arg`
only_dots <- FALSE
f(foo(bar))
# Here, while `arg` is bound to a promise just like in the last
# call, argument instrospection is not given the same scope as lazy
# evaluation. dots_inspect() does not follow symbols bound to a
# promise and thus returns information about ..1, the expression
# supplied at the first call site (before forwarding dots). The
# expression is `arg` (a symbol that is bound to a promise), to be
# evaluated in f's call frame.
only_dots <- TRUE
f(foo(bar))
Run the code above in your browser using DataLab