Как запоминать функцию при запуске пакета в R
Я работаю над пакетом R, который обертывает вызовы API. Чтобы уменьшить количество фактических вызовов и ускорить процесс, я запомнил функцию, выполняющую вызов API. Для этого я создал следующую функцию, которая позволяет установить каталог кеша:
memoise_fromJSON <- function(cache_dir = tempdir()) {
memoise::memoise(jsonlite::fromJSON,
cache = memoise::cache_filesystem(cache_dir))
}
Для создания мемоизированной функции я использую
memoised_fromJSON <- memoise_fromJSON()
Теперь, когда мне нужна мемоизованная функция в моем пакете много раз, я хотел бы запомнить эту функцию при запуске пакета. Я попытался
.onLoad <- function(libname, pkgname) {
memoised_fromJSON <- my_package:::memoise_fromJSON()
}
но мне все еще нужно бежать memoised_fromJSON <- memoise_fromJSON()
чтобы заставить его работать.
Итак, мои вопросы:
- Есть ли возможность запоминать функцию при запуске пакета?
- Если да, как я могу сохранить функцию таким образом, чтобы она не отображалась в глобальной среде?
Думаю, вопросы как-то связаны. Правильно ли я понимаю, что моя попытка с.onLoad()
не работает, потому что он создает мемоизированную функцию в среде .onLoad()
?
PS: Я знаю, что не могу изменить cache_dir
при загрузке пакета, но я хочу установить разумное значение по умолчанию, которое позволит начать работу без лишних слов. Однако при этом сохраняется возможность при необходимости изменить каталог кеша.
3 ответа
Вы выполняете локальное задание внутриonLoad
функция.
И вы не можете просто выполнить (пакетное) глобальное назначение, поскольку пространство имен пакета заблокировано. Что ты можешь сделать, это
- Создайте новую среду с помощью
new.env(parent = parent.env(environment())
(параметр гарантирует, что эта среда находит объекты, определенные в пространстве имен вашего пакета). - Назначьте мемоизированные функции внутри этой среды.
attach
среда. Это, как правило, не одобряется и фактически принесет вам красную карточку от CRAN, если вы попытаетесь отправить ее. Фактически, ваш.onLoad
функция не должна вызыватьattach
поскольку пользователь может захотеть использовать ваш пакет, не прикрепляя его. Но я думаю, что это законно, если вы сделаете это в.onAttach
скорее, чем.onLoad
. Боюсь, что сопровождающие CRAN могут не согласиться; опять же, есть приоритет для пакетов CRAN, которые вызываютattach
при определенных обстоятельствах, например {devtools}.
У вас может быть мемоизированная функция в вашем пакете, нет необходимости
.onLoad()
колдовство:
Имейте в любом из ваших скриптов:
memoised_fromJSON <- memoise::memoise(
jsonlite::fromJSON,
cache = memoise::cache_filesystem(cache_dir))
Вы можете добавлять объекты в свое пространство имен во время
.onLoad
, хотя здесь вам это не нужно, и способ сделать это:
.onLoad <- function(libname, pkgname) {
your_object <- your_object_builder()
ns <- asNamespace(pkgname)
namespaceExport(ns, "your_object ")
}
Если вам нужно экспортировать его, используя {roxygen2}, вам необходимо иметь в ваших скриптах:
#' your title
#' @whatever tags you need
#' @export
your_object <- NULL
И почему бы не объявить функцию memoized напрямую в исходниках R?
#' Memoised version of [jsonlite::fromJSON]
#' @inherit jsonlite::fromJSON
#'
#' @export
memoised_fromJSON <- memoise::memoise(jsonlite::fromJSON,
cache = memoise::cache_filesystem(tempdir()))
Это должно выполнить работу без каких-либо примечаний или предупреждений при проверке R CMD.