If I try to set NA
or another special variable in R I 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).
R objects are (mostly) immutable. If we change any element of x, the value of y will not be automatically changed. This is exactly what we would expect mathematically. The R code x[[2]] = 1 gives the illusion of modifying the list referenced by x.
Such variables cannot change their value or state. Therefore, once we assign them the value during declaration we cannot make changes in the future if a need arises. Moreover, if we try to change an immutable variable python gives an error.
If you've used Shiny for R, you probably haven't had to worry about mutable objects; almost all objects in R are immutable: vectors, matrices, lists, data frames.
The R6 class system, created in R via the R6 package, allows to define objects that are mutable.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With