且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

R - 如何找到从被调用函数内部调用函数的环境?

更新时间:2023-11-24 12:16:52

TL,DR: parent.frame() not parent.frame(environment());evalq 不是 eval.

TL,DR: parent.frame() not parent.frame(environment()); evalq not eval.

parent.frame 接受参数 n 是要返回的代数,而不是 environment() 调用的结果(这是一个环境).如果你把它放在 parent.frame() 调用之外,你就没事了.

parent.frame takes argument n being number of generations to go back, not the result of an environment() call (which is an environment). If you leave it out of the parent.frame() call you're fine.

此外,您的示例代码并没有像您预期的那样工作,因为您的 environment() 命令在对 eval 的调用中被评估,然后才被评估作为 eval 的一部分.IE.您必须将您的参数引用到 eval.或者,使用 evalq 而不是 eval.

Also, yoru example code doesn't work as you expect, because your environment() command is being evaluated in the call to eval, before being evaluated as part of eval. I.e. you must quote your argument to eval. Alternatively, use evalq rather than eval.

例如

uniqueid <- function(name) {
  print(parent.frame())
}
hello <- new.env()
hello$env <- new.env()
evalq(envir=hello$env, {
  print(environment()) # prints hello$env
  print(hello$env)     # prints hello$env
  print(hello)         # prints hello
  uniqueid('hi')       # prints hello$env
})

例如这将获取环境 ID 并将其添加到 name:

E.g. this will get the environment ID and add it to the name:

uniqueid <- function(name) {
    # GlobalEnv etc have names; hello doesn't
    envName <- environmentName(parent.frame())
    # get the environment ID from the parent.frame() output if no name
    if (envName == "") {
        p <- parent.frame()
        envName <- sub('<environment: (.*)>', '\\1', capture.output(p))
    }
    return(paste(envName, name, sep=':'))
}
uniqueid('x') # R_GlobalEnv:x
print(hello) # <environment: 0x4641fa0>
evalq(envir=hello, uniqueid('x')) # "0x4641fa0:x"
print(hello$env) # <environment: 0x4640e60>
evalq(envir=hello$env, uniqueid('x')) # "0x4640e60:x"