如何在我的 R 包中使用 get0 仅在包命名空间内进行搜索?

How can I use get0 in my R package to search only within package namespace?

假设我的包中有一个内部函数,称它为is_(),如果is(),它可以被认为是一个更通用的版本。特别是,它搜索用于判断提供的对象是否为给定的 class 的专用函数。例如,is_() 可能编程为:

is_ <- function(obj, class) {
  if (exists(paste0("is.", class))) {
     get0(paste0("is.", class))(obj)
  }
  else inherits(obj, class)
}

那样的话,如果我在我的包中进行参数检查,我可以运行类似

的东西
is_(x, "numeric_vector")

我定义的地方

is.numeric_vector <- function(x) is.numeric(x) && is.null(dim(x))

在我的包裹里。

is.numeric_vector() 在我的包外定义时出现问题,例如,由用户加载的另一个包。在那种情况下,exists()get0() 都会尽可能地找到函数,但我想将搜索限制为在我的包中定义并包含在我的包的命名空间中的函数(即所有导入的包)。 envirinherits 参数似乎达到了我想要的效果,但我不知道如何提供它们以获得我想要的结果。我怎样才能限制 get0() 只在我的包的命名空间中搜索它的参数?

问题是您的包命名空间将从继承自全局环境的基本命名空间继承。有关更详细的解释,请参见此处:https://adv-r.hadley.nz/environments.html#namespaces。如果您想更好地控制符号查找,则需要自己完成这项工作。您可以在您的程序包

中包含您自己的 get 函数
# These are private helpers that do not need to be exported from your package.
.pkgenv <- environment()
get1 <- function(name, env = .pkgenv) {
  if (identical(env, emptyenv())) {
    NULL
  } else if (identical(env, globalenv())) {
    # stop at global env
    NULL
  } else if (exists(name, envir=env, inherits = FALSE)) {
    env[[name]]
  } else {
    # try parent
    get1(name, parent.env(env))
  }
}

这将在环境中递归搜索符号,但在全局环境中停止。您可以将它与 is_ 函数一起使用,例如

is_ <- function(obj, class) {
  if (!is.null(fn <- get1(paste0("is.", class)))) {
    fn(obj)
  } else {
    inherits(obj, class)
  }
}

这里我们只是检查是否为空,而不是单独验证名称然后检索值。如果 get1 将被称为一堆,您可能需要考虑缓存结果,这样您就不必总是遍历继承树。