.First.lib идиома в пакетах R - PullRequest
       2

.First.lib идиома в пакетах R

4 голосов
/ 06 декабря 2010

Я вижу следующую идиому в функции .First.lib во многих пакетах R:

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 ]

11 голосов
/ 06 декабря 2010

Такая идиома старинна. Пакеты должны иметь пространства имен и использовать .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")
}

Лучше всего избежать сложного дела с вызовом функции lazyLoad, просто добавив его в файл DESCRIPTION:

LazyLoad: true
3 голосов
/ 07 декабря 2010

Вы спрашиваете, почему он ищет .First.Lib, когда сценарий удалил его ранее.lazyLoad загружает базу данных R объектов, которая в приведенном выше коде загружается в среду myEnv.Не исключено, что набор объектов, загруженных в эту среду, содержит .First.Lib, и именно этот код ищет.Действительно, я предполагаю, что целью было только запустить .First.Lib, который был сохранен в загруженной базе данных объекта.

Еще одна распространенная идиома в пакетах без NAMESPACE, это (из веганаpackage):

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

Загружает скомпилированный код, готовый к использованию, и печатает простое стартовое сообщение с именем пакета и номером версии.По духу это похоже на .onLoad из ответа @ Romain, но без NAMESPACE.

...