【发布时间】:2022-02-03 04:13:25
【问题描述】:
所以我想我有点知道这里发生了什么,但我很难找到参考(在 SO 或 R 文档中),所以我想把它说出来,看看人们是否可以阐明.
我有一个 R 包,在 utils.R 文件的顶层(不在任何函数内)包含以下代码:
S3_BUCKET <- Sys.getenv('S3_BUCKET')
CACHE_DIR <- if (S3_BUCKET == "") {
'cache/foo'
} else {
paste0('s3://', S3_BUCKET, '/dir/cache/foo')
}
print(paste("CACHE_DIR:", CACHE_DIR))
当我通过devtools::load_all('.') 加载包时,这在“开发模式”下工作正常,但是当我在我的环境中安装包并通过library(mypkg) 加载它时,此代码中的Sys.getenv('S3_BUCKET') 总是返回空字符串(已通过检查mypkg:::S3_BUCKET 验证)。
我的假设是在包加载期间评估“包级代码”时尚未设置环境变量。如果是这样 - 这是否记录在任何地方,如果没有,将其添加到文档的正确位置在哪里?还是应该修复的错误?
看起来stdout 可能还没有设置(对于包?),因为print 输出似乎永远不会出现。
我要采用的解决方案是将其转换为 .onLoad 回调,我确信这是更好的做法:
GLOBALS <- new.env()
GLOBALS$CACHE_DIR <- 'cache/foo'
.onLoad <- function(libname, pkgname) {
S3_BUCKET <- Sys.getenv('S3_BUCKET')
if (S3_BUCKET != "") {
assign('CACHE_DIR', paste0('s3://', S3_BUCKET, '/dir/cache/foo'), GLOBALS)
print(paste("CACHE_DIR:", CACHE_DIR))
}
}
这按预期工作。
【问题讨论】:
-
@MikaelJagan 这比我想象的更令人惊讶。事实上,我的队友提出了这个建议,但我立即将其驳回。 =) 是否在任何地方记录了顶级代码的时间安排?
-
我将我的评论迁移到了一个答案中 - 如果我无意中让事情变得不太清楚,请告诉我......
标签: r package environment-variables startup