R包中的.First.lib习语

时间:2010-12-06 17:50:36

标签: r packages

我在很多R包中的.First.lib函数中看到以下习语:

fullName <- paste("package", pkgname, sep=":")
myEnv <- as.environment(match(fullName, search()))
barepackage <- sub("([^-]+)_.*", "\\1", pkgname)
dbbase <- file.path(libname, pkgname, "R", barepackage)
rm(.First.lib, envir = myEnv)
lazyLoad(dbbase, myEnv)
if(exists(".First.lib", envir = myEnv, inherits = FALSE)) {
    f <- get(".First.lib", envir = myEnv, inherits = FALSE)
    if(is.function(f))
        f(libname, pkgname)
    else
        stop(gettextf("package '%s' has a non-function '.First.lib'",
                      pkgname),
             domain = NA)
}

我知道在加载包时会运行.First.lib函数。

我知道上面的代码定义了一个包的环境并设置了一个路径,但是我不明白为什么它在显式删除.First.lib函数之后正在寻找一个.First.lib函数。是什么让上述成语如此普遍?将它包含在R包中是“最佳实践”吗?

2 个答案:

答案 0 :(得分:11)

那种成语很古老。包应该有名称空间并使用.onLoad,.onUnload和.onAttach。例如:

.onLoad <- function(libname, pkgname){
     # do whatever needs to be done when the package is loaded
     # some people use it to bombard users with 
     # messages using 
     packageStartupMessage( "my package is so cool" )
     packageStartupMessage( "so I will print these lines each time you load it")
}

只需将其添加到DESCRIPTION文件中,最好避免调用lazyLoad函数的业务:

LazyLoad: true

答案 1 :(得分:3)

当脚本先前删除它时,您会问为什么要查找.First.LiblazyLoad加载R对象的数据库,在上面的代码中将其加载到环境myEnv中。加载到该环境中的对象集包含.First.Lib并且正是代码正在寻找的并不是不可想象的。实际上,我的意图是运行存储在加载的对象数据库中的.First.Lib

没有NAMESPACE的包装中的另一个常见习语是(来自纯素包):

.First.lib <- function(lib, pkg)  {
    library.dynam("vegan", pkg, lib)
    packageStartupMessage("This is vegan ",
                          utils::packageDescription("vegan", field="Version"),
                          appendLF = TRUE)
}

这将加载已准备好使用的已编译代码,并打印包含软件包名称和版本号的简单启动消息。这与@ Romain的答案的.onLoad精神相似,但没有NAMESPACE。