Reputation: 20560
[This question has been resolved in the chat room, by Spacedman, but I'm posting it for others' benefit in the future.]
I have a function, myFunc
, which creates localFunc
inside of it. (NB: this is not in a package, but in the global environment.) I'd like to know where localFunc
exists in the search path, as I'd like to analyze it via mvbutils::foodweb
.
Here is an example:
myFunc <- function(){
require(data.table)
require(mvbutils)
localFunc <- function(x){
return(as.data.table(x))
}
vecPrune <- c("localFunc",ls("package:data.table"))
ix <- match("data.table",search())
tmpWeb <- foodweb(where = c(1,ix), prune = vecPrune, plotting = FALSE)
return(tmpWeb)
}
However, a call to myFunc()
does not seem to indicate that localFunc
calls data.table()
. This is incorrect - what gives?
(NB: The where
argument specifies the search path.)
Update 1: As Tommy and Spacedman point out, the trick is to specify environment()
. The call to foodweb()
refers to where = c(1, ix)
. The index 1
is a mistake. That arose from thinking that .GlobalEnv
, which is often (always?) the first item in the search()
vector, is the right place to search. That is erroneous. Instead, one should refer to environment()
, and the correct call is below. (NB: ix
specifies the location of data.table()
in the search()
output.)
tmpWeb <- foodweb(where = c(environment(),ix), prune = vecPrune, plotting = FALSE)
This appears in the answer to this question, in a function called checkScriptDependencies
, which wraps the code from an R script file into a local function, which is then analyzed by foodweb
. This is a limited example of how to use environment()
, and Tommy has given a good explanation of how to use it and similar functions in this context.
Upvotes: 40
Views: 29805
Reputation: 40821
To get the current environment, just call environment()
.
In general, sys.frame
returns any of the environments currently on the call stack, and sys.nframe
returns the current depth of the call stack. sys.frames
returns a list of all environments on the call stack.
environment(f)
returns the closure environment for a function f
(where it will look for functions and global variables).
parent.env(e)
returns the parent environment where it will look if a symbol is not found in e
.
f <- function() {
function() list(curEnv=environment(), parent=parent.env(environment()),
grandParent=parent.env(parent.env(environment())), callStack=sys.frames(),
callStackDepth=sys.nframe())
}
g <- function(f, n=2) if (n>2) g(f, n-1) else f()
floc <- f() # generate a local function
g(floc, 3) # call it
This will call the local function floc
with a stack depth of 3. It returns a list with the current environment, it's parent (the local environment in f
), and it's grand parent (where f
was defined, so globalenv
). It also returns the list of stack frames (environments). These are the environments for the recursive calls in g
(except the last one which is the current environment of floc
).
Upvotes: 56