Open HenrikBengtsson opened 8 years ago
Looking at the usage handler for base::with()
we see that it is conditioned on a setting skipWith
, which cannot be set via codetools::findGlobals()
:
addCollectUsageHandler("with", "base", function(e, w) {
w$enterGlobal("function", "with", e, w)
if (identical(w$skipWith, TRUE))
walkCode(e[[2]], w)
else collectUsageArgs(e, w)
})
This is why we get:
> codetools::findGlobals(function() with(df, sum(a)))
[1] "a" "df" "sum" "with"
However, we can override this as:
codetools:::addCollectUsageHandler("with", "base", function(e, w) {
w$enterGlobal("function", "with", e, w)
walkCode(e[[2]], w)
})
such that only the first argument is checked:
> codetools::findGlobals(function() with(df, sum(a)))
[1] "df" "with"
Importantly, addCollectUsageHandler()
completely ignores the 2nd argument (where
) right now:
# 'where' is ignored for now
addCollectUsageHandler <- function(v, where, fun)
assign(v, fun, envir = collectUsageHandlers)
The codetools package does indeed handle some non-standard evaluation (NSE) expressions, e.g.
library()
without quotes:Note how
tools
is not identified as a global/unknown; this is because codetools knows howlibrary()
works.This is done by (internal) usage-handler functions, e.g. for
base::library()
it sets up:This can be retrieved as:
There are several usage handlers set up this way: