R如何在加载时使变量可用于命名空间

问题描述 投票:5回答:1

在我的一个软件包中,我使用.onAttach钩子运行一些R代码,然后使用assign将值作为包变量之一。我这样做是因为variable取决于某个文件的内容,这个文件可以在一个会话和另一个会话之间切换。我使用的代码如下:

.onAttach <- function(libname, pkgname) {
   variable <- some_function()
   assign("variable", variable, envir = as.environment("package:MyRPackage"))
}

当我用library(MyRpackage)附上包时,我可以使用variable

然而,不可能像MyRPackage::variable那样做(除非我已经用library(MyRpackage)附上了包。

我知道这是因为我应该将该代码放在.onLoad钩子中,但是我无法进行赋值以使其有效。

我试过了

.onLoad <- function(libname, pkgname) {
   variable <- some_function()
   assign("variable", variable, envir = as.environment("namesoace:MyRPackage"))
}

.onLoad <- function(libname, pkgname) {
   variable <- some_function()
   assign("variable", variable, envir = asNamespace("MyRPackage"))
}

但是当我运行MyRPackage:::variable而不使用library附加包时,它们都失败并出现一些错误。

在.onLoad钩子中进行赋值的正确方法是什么?

r devtools r-package
1个回答
11
投票

按照this answer中相关问题的方法,你可以改变你的.onLoad()函数:

.onLoad <- function(libname, pkgname) {
    variable <- some_function()
    assign("variable", variable, envir = parent.env(environment()))
}

然后你可以使用variable访问MyRPackage:::variable而不附加包。我不知道你用some_function()做了什么,所以我尝试了以下虚拟包:

.onLoad <- function(libname, pkgname) {
    variable <- 42
    assign("variable", variable, envir = parent.env(environment()))
}

在新的R会议中,结果是

> MyRPackage:::variable
[1] 42

Further explanation

来自Hadley Wickham的Advanced R

有四种特殊环境:

...

  • environment()是当前环境。

...

您可以使用ls()列出环境框架中的绑定,并使用parent.env()查看其父级。

因此,如果我们进一步修改.onLoad()函数,我们可以看到这个:

.onLoad <- function(libname, pkgname) {
    print(environment()) # For demonstration purposes only;
    print(parent.env(environment())) # Don't really do this.
    variable <- 42
    assign("variable", variable, envir = parent.env(environment()))
}

然后开始R会话结果

<environment: 0x483da88>
<environment: namespace:MyRPackage>

在会话开始时打印到控制台。这允许你在环境variable中分配namespace:MyRPackage,即使尝试assign("variable", variable, envir = namespace:MyRPackage)会导致错误

错误:“MyRPackage”的包或命名空间加载失败:

.onLoad在'MyRPackage'的loadNamespace()中失败,详细信息:

call:get(name,envir = ns,inherits = FALSE)

错误:找不到对象'名称空间'

安装包时。

© www.soinside.com 2019 - 2024. All rights reserved.