使变量在R中不可变

Bob*_*sen 6 r

如果我尝试NA在RI中设置或其他特殊变量,则会得到一个很好的警告:

> NA <- 1
Run Code Online (Sandbox Code Playgroud)

NA <-1中的错误:分配的左侧无效(do_set)

使用我自己的代码中定义的变量是否可以实现相同目的?

我试图lockBinding('foo', parent.env(environment())在包中使用它,.onLoad()但是这将使我很高兴地隐藏锁定的绑定。

扩大:

在一个包中,myPackage我可以创建以下init.R文件:

#' @export
foo <- 1

.onLoad <- function(libname, pkgname) {
  lockBinding('foo', parent.env(environment()))
}
Run Code Online (Sandbox Code Playgroud)

devtools::document()R CMD INSTALL现在,它做了:

> library(myPackage)
> foo
[1] 1
> foo <- 2
> foo
[1] 2
> myPackage::foo
[1] 1
> rm(foo)
> foo
[1] 1 
Run Code Online (Sandbox Code Playgroud)

我要这样做,以免foo蒙上阴影(NA不可能这样)。

Kon*_*lph 6

无法获得与保留名称相同的效果。保留名称根本不能被遮蔽(您可以分配给`NA`它,但它不能被遮蔽NA-评估NA根本就不执行变量查找)。而变量始终可以。

顺便说一句,您的lockBinding调用.onLoad是多余的:默认情况下,包符号的绑定是锁定的。


Moo*_*per 6

您可以覆盖<-,如果在全局环境中完成,这通常是一个非常糟糕的主意,但如果您知道自己在做什么,那么在特定环境中完成为什么不呢:

X <- new.env()
X$`<-` <- function(e1, e2) {
  sc <- sys.call()
  if(identical(sc[[2]], quote(foo)))
     stop("invalid left-hand side to assignment")
  else
    eval.parent(do.call(substitute, list(sc, list(`<-` = base::`<-`))))
}

with(X, foo <- 42)
#> Error in foo <- 42: invalid left-hand side to assignment
with(X, bar <- 42)
X$bar
#> [1] 42
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v0.3.0)于 2019-08-19 创建