Why should it make an exception for cases where the about-to-be-assigned-to name is present in the global environment? I think it should warn or give an error if the altered variable is in any environment on the search list.
-Bill On Sun, Mar 19, 2023 at 10:54 AM Duncan Murdoch <murdoch.dun...@gmail.com> wrote: > I think that should be the default behaviour. It's pretty late to get > that into R 4.3.0, but I think your proposal (with check.superassignment > = FALSE being the default) could make it in, and 4.4.0 could change the > default to TRUE. > > Duncan > > > > On 19/03/2023 12:08 p.m., Henrik Bengtsson wrote: > > I'd like to be able to prevent the <<- assignment operator ("super > > assignment") from assigning to the global environment unless the > > variable already exists and is not locked. If it does not exist or is > > locked, I'd like an error to be produced. This would allow me to > > evaluate expressions with this temporarily set to protect against > > mistakes. > > > > For example, I'd like to do something like: > > > > $ R --vanilla > >> exists("a") > > [1] FALSE > > > >> options(check.superassignment = TRUE) > >> local({ a <<- 1 }) > > Error: object 'a' not found > > > >> a <- 0 > >> local({ a <<- 1 }) > >> a > > [1] 1 > > > >> rm("a") > >> options(check.superassignment = FALSE) > >> local({ a <<- 1 }) > >> exists("a") > > [1] TRUE > > > > > > BACKGROUND: > > > > From help("<<-") we have: > > > > "The operators <<- and ->> are normally only used in functions, and > > cause a search to be made through parent environments for an existing > > definition of the variable being assigned. If such a variable is found > > (and its binding is not locked) then its value is redefined, otherwise > > assignment takes place in the global environment." > > > > I argue that it's unfortunate that <<- fallbacks back to assigning to > > the global environment if the variable does not already exist. > > Unfortunately, it has become a "go to" solution for many to use it > > that way. Sometimes it is intended, sometimes it's a mistake. We > > find it also in R packages on CRAN, even if 'R CMD check' tries to > > detect when it happens (but it's limited to do so from run-time > > examples and tests). > > > > It's probably too widely used for us to change to a more strict > > behavior permanent. The proposed R option allows me, as a developer, > > to evaluate an R expression with the strict behavior, especially if I > > don't trust the code. > > > > With 'check.superassignment = TRUE' set, a developer would have to > > first declare the variable in the global environment for <<- to assign > > there. This would remove the fallback "If such a variable is found > > (and its binding is not locked) then its value is redefined, otherwise > > assignment takes place in the global environment" in the current > > design. For those who truly intends to assign to the global, could > > use assign(var, value, envir = globalenv()) or globalenv()[[var]] <- > > value. > > > > 'R CMD check' could temporarily set 'check.superassignment = TRUE' > > during checks. If we let environment variable > > 'R_CHECK_SUPERASSIGNMENT' set the default value of option > > 'check.superassignment' on R startup, it would be possible to check > > packages optionally this way, but also to run any "non-trusted" R > > script in the "strict" mode. > > > > > > TEASER: > > > > Here's an example why using <<- for assigning to the global > > environment is a bad idea: > > > > This works: > > > > $ R --vanilla > >> y <- lapply(1:3, function(x) { if (x > 2) keep <<- x; x^2 }) > >> keep > >> [1] 3 > > > > > > This doesn't work: > > > > $ R --vanilla > >> library(purrr) > >> y <- lapply(1:3, function(x) { if (x > 2) keep <<- x; x^2 }) > > Error in keep <<- x : cannot change value of locked binding for 'keep' > > > > > > But, if we "declare" the variable first, it works: > > > > $ R --vanilla > >> library(purrr) > >> keep <- 0 > >> y <- lapply(1:3, function(x) { if (x > 2) keep <<- x; x^2 }) > >> keep > >> [1] 3 > > > > /Henrik > > > > PS. Does the <<- operator have an official name? Hadley calls it > > "super assignment" in 'Advanced R' > > (https://adv-r.hadley.nz/environments.html), which is where I got it > > from. > > > > ______________________________________________ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > [[alternative HTML version deleted]] ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel