If I try to set NA
or another special variable in RI get a nice warning:
> NA <- 1
Error in NA <- 1 : invalid (do_set) left-hand side to assignment
Is it possible to achieve the same with variables defined in my own code?
I tried to use lockBinding('foo', parent.env(environment())
inside my package .onLoad()
but that will happily allow me to shadow the locked binding.
In a package myPackage
I can create the following init.R
file:
#' @export
foo <- 1
.onLoad <- function(libname, pkgname) {
lockBinding('foo', parent.env(environment()))
}
devtools::document()
and R CMD INSTALL
it and now do:
> library(myPackage)
> foo
[1] 1
> foo <- 2
> foo
[1] 2
> myPackage::foo
[1] 1
> rm(foo)
> foo
[1] 1
I want to make it so that foo
doesn't get shadowed (like NA
can't be).
There's no way to get the same effect as with reserved names. A reserved name simply cannot be shadowed (you can assign to `NA`
but it never shadows NA
— evaluating NA
simply never performs a variable lookup). Whereas variables always can.
Incidentally, your lockBinding
call in .onLoad
is redundant: Bindings for package symbols are locked by default.
You could override <-
, this would be a very bad idea in general if done in the global environment, but done in a specific environement if you know what you're doing why not :
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
Created on 2019-08-19 by the reprex package (v0.3.0)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.