Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making variables immutable in R

Tags:

r

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.

To expand:

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).

like image 400
Bob Jansen Avatar asked Aug 16 '19 15:08

Bob Jansen


People also ask

Are R variables mutable?

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.

What does it mean for a variable to be immutable?

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.

Are vectors in R immutable?

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.

Which of the following classes in R produce objects that are mutable?

The R6 class system, created in R via the R6 package, allows to define objects that are mutable.


1 Answers

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.

like image 181
Konrad Rudolph Avatar answered Nov 15 '22 06:11

Konrad Rudolph