4

我在一个包装 API 调用的 R 包上工作。为了减少实际调用的次数并加快速度,我记住了进行 API 调用的函数。为此,我创建了以下函数,它允许设置缓存目录:

memoise_fromJSON <- function(cache_dir = tempdir()) {
  memoise::memoise(jsonlite::fromJSON,
                   cache = memoise::cache_filesystem(cache_dir))
}

要创建我使用的记忆功能

memoised_fromJSON <- memoise_fromJSON()

现在,由于我在我的包中多次需要 memoised 函数,我想在包启动时记住这个函数。我试过了

.onLoad <- function(libname, pkgname) {
  memoised_fromJSON <- my_package:::memoise_fromJSON()
}

但我仍然需要跑步memoised_fromJSON <- memoise_fromJSON()才能让它工作。

所以我的问题是:

  1. 是否有可能在包启动时记住一个函数?
  2. 如果是这样,我怎样才能以在全局环境中不可见的方式记忆该功能?

我想,这些问题在某种程度上是相关的。我的理解是否正确,我的尝试.onLoad()不起作用,因为它在 的环境中创建了记忆功能.onLoad()


PS:我知道,我无法更改cache_dirat 包加载,但我想设置一个合理的默认值,这样就可以毫不费力地启动。但是,这保留了在需要时更改缓存目录的可能性。

4

1 回答 1

3

您正在函数内部执行本地分配onLoad

而且您不能简单地执行(包)全局分配,因为包名称空间已锁定。你能做的是

  1. 通过创建一个新环境new.env(parent = parent.env(environment())(该参数确保此环境找到在您的包命名空间中定义的对象)。
  2. 在该环境中分配记忆功能。
  3. attach环境。现在,这通常是不受欢迎的,如果你尝试提交它,实际上会让你从 CRAN 获得一张红牌。事实上,你的.onLoad函数不能调用attach,因为用户可能想使用你的包而不附加它。但我认为如果你这样做是合法的,.onAttach而不是.onLoad. 恐怕 CRAN 维护者可能不同意。再说一次,在特定情况下调用的 CRAN 包有优先权attach,例如 {devtools}。
于 2019-12-30T23:16:27.977 回答