从.onLoad包函数内调用getNamespaceExports()

从.onLoad包函数内调用getNamespaceExports(),r,scope,namespaces,package,environment,R,Scope,Namespaces,Package,Environment,为什么从.onLoad上下文自动调用getNamespaceExports时返回的结果与从外部代码调用时不同 假设我们有一个名为testpackage的R包。此包包含一个名为hello.R的R文件,其中包含以下内容: #' @export package_var <- "some value" #' @export call_when_onload <- function(pkgname) { print(getNamespaceExports(pkgname)) prin

为什么从.onLoad上下文自动调用getNamespaceExports时返回的结果与从外部代码调用时不同

假设我们有一个名为testpackage的R包。此包包含一个名为hello.R的R文件,其中包含以下内容:

#' @export
package_var <- "some value"

#' @export
call_when_onload <- function(pkgname) {
  print(getNamespaceExports(pkgname))
  print(do.call("getNamespaceExports",list(pkgname),envir = globalenv()))
}

.onLoad <- function(libname, pkgname){
  print(sprintf("Executing onload procedure for package %s...",pkgname))
  call_when_onload(pkgname)
}
现在问题来了:在记录和构建包之后,librarytestpackage返回以下内容:

> library(testpackage)
[1] "Executing onload procedure for package testpackage..."
character(0)
character(0)
但是,当我调用testpackage::call_when_onload testpackage时,正如预期的那样,我得到了以下输出:

> testpackage::call_when_onload("testpackage")
[1] "package_var"      "call_when_onload"
[1] "package_var"      "call_when_onload"
为什么??如何使.onLoad函数像从外部上下文调用时一样计算上述表达式?

Per?.onLoad强调:

加载后,loadNamespace查找名为.onLoad的钩子函数,并在密封命名空间和处理导出之前使用两个未命名的参数调用它

因此,onLoad在从包中导出任何内容之前运行

如果要获取所有导出的对象,一种方法是从包中读取名称空间文件并对其进行处理:

f <- base::system.file("NAMESPACE", package="pkgname")
objs <- readLines(f)
exps <- objs[grepl("export", objs)]
sub("^export[^\\(]*\\(([^\\)]+)\\)", "\\1", exps)
可能需要进行一些调整,以精确匹配getNamespaceExports的输出。

可能是这样吗。在将导出的对象写入全局环境之前执行onLoad?
f <- base::system.file("NAMESPACE", package="pkgname")
objs <- readLines(f)
exps <- objs[grepl("export", objs)]
sub("^export[^\\(]*\\(([^\\)]+)\\)", "\\1", exps)