我正在尝试将变量true,false,na和null的Pascal-Case版本分配到我的R包中。这很容易做到,但我也想锁定绑定以防止重命名变量。
# An anti-example from the base libraries
F <- TRUE
T <- FALSE
T && T
FALSE
我无法弄清楚如何锁定包中的变量以防止进一步修改。以下模拟包不起作用
# test.R
True <- TRUE
lockBinding('True', environment())
#DESCRIPTION
Collate:
'test.R'
运行R CMD检查时出现以下错误:
Error in eval(expr, envir, enclos) :
cannot change value of locked binding for 'True'
锁定R包变量的正确方法是什么,因此无法重新分配?
编辑:包含错误的错误消息。
答案 0 :(得分:12)
通常不回答你的问题。我同意@IShouldByABoat说还有更多的事情,你指出的简单结构的包不会产生你看到的错误。可能你试图在你的代码中的其他地方修改True(!)或者你的.Rprofile或.RData文件中有一些干扰 - 将你的支票作为R --vanilla CMD check
运行。
函数和符号在包名称空间中定义,例如
library(plyr) ## load package name space, attach to the search() path
getNamespace(plyr) ## package name space
ls(getNamespace(plyr)) ## symbols defined in the name space
plyr::llply ## definition of `llply` in the name space
包名称空间在加载后被锁定
assign("llply", identity, envir=getNamespace("plyr"))
## Error in assign("llply", identity, envir = getNamespace("plyr")) :
## cannot change value of locked binding for 'llply'
在命令行分配一个类似命名的变量会在.GlobalEnv
(搜索()路径上的第一个位置)创建一个新变量,而不是修改包名称空间中的变量
ls() ## no symbol 'llply' in .GlobalEnv
llply <- identity ## new symbol 'llply' in .GlobalEnv
llply(10) ## use first llply function in search(), i.e., in .GlobalEnv
plyr::llply(10) ## circumvent search path and use llply from plyr name space
所以代码如
True <- TRUE
lockBinding("True", environment())
仅在创建True时添加锁定绑定,直到加载包为止;之后,无论如何都要锁定绑定。
也许您想在用户的.GlobalEnv中创建一个变量True,并使其无法更改。当用户的当前.GlobalEnv可见时,必须在加载(或附加)包时完成此操作,类似
.onAttach <- function(...) {
assign("True", TRUE, .GlobalEnv)
lockBinding("True", .GlobalEnv)
}
这只会锁定.GlobalEnv中的绑定,因此无法更改,但不会阻止用户将其删除(例如,使用rm("True")
)。与用户的.GlobalEnv混淆可能也会激怒您的用户,而不仅仅是进一步的编程议程。