2017-08-31 94 views
0

爲什麼getNamespaceExports()在從外部代碼調用時從.onLoad上下文自動調用時會返回不同的結果?getNamespaceExports()從.onLoad包函數內調用

讓我們假設我們有一個名爲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) 
} 

包裝上有一個空間文件看起來像這樣:

# Generated by roxygen2: do not edit by hand 

export(call_when_onload) 
export(package_var) 

現在,這裏的問題是:記錄和建設後包,library("testpackage")返回此:

> library(testpackage) 
[1] "Executing onload procedure for package testpackage..." 
character(0) 
character(0) 

但是當我打電話testpackage::call_when_onload("testpackage"),我得到下面的輸出(就像EXPE c):

> testpackage::call_when_onload("testpackage") 
[1] "package_var"  "call_when_onload" 
[1] "package_var"  "call_when_onload" 

爲什麼?我怎樣才能使.onLoad函數評估上面的表達式就像他們在從外部上下文中調用時一樣?

+0

在將導出的對象寫入全局環境之前,是否會執行'.onLoad'? – nilsole

回答

1

?.onLoad(重點煤礦):

加載後,loadNamespace查找名爲.onLoad一個鉤子函數和密封命名空間和加工出口前調用它(有兩個未命名的參數)

因此.onLoad在從包中導出任何東西之前運行。

如果你想獲得所有的出口對象,一個方法是從包讀取空間文件,並對其進行處理:

f <- base::system.file("NAMESPACE", package="pkgname") 
objs <- readLines(f) 
exps <- objs[grepl("export", objs)] 
sub("^export[^\\(]*\\(([^\\)]+)\\)", "\\1", exps) 

一些調整,可能有必要的getNamespaceExports輸出完全匹配。