I am trying to update a global list from inside a function.
Here is the code that does not work (can be sourced as a whole file):
require(rlang)
(my_list <- list(a = 1, b = "two", c = "set outside"))
print( paste("my_list$c is" , my_list$c) )
my_function <- function(x = 1, y = 2, parent_object_name = "my_list") {
z <- x + y # do some stuff (irrelevant here)
some_names <- "updated inside"
upper_env_object_name <- paste0(parent_object_name, "$c")
# browser()
# env_poke(env = env_tail(), upper_env_object_name, some_names) # does not work
# env_poke(env = env_parents()[[1]], upper_env_object_name, some_names) # does not work
env_poke(env = caller_env(), upper_env_object_name, some_names ) # creates `my_list$c` character vector
# force(env_poke(env = caller_env(), upper_env_object_name, some_names )) # creates `my_list$c` character vector
# browser()
# env_poke(env = caller_env(), paste0("as.list(",upper_env_object_name,")"), some_names) # creates as.list(my_list$c)` character vector
return(z)
}
my_function(x = 1, y = 2, parent_object_name = "my_list")
print(class(`my_list$c`))
print( `my_list$c`)
print( paste("my_list$c is" , my_list$c) )
I found this but it does not help: Updating a nested list object in the global environment from within a function in R
Tried also with assign, and specifying the environment.
Background: I have some S3- subclases and want to keep track of them in the parent class object, which is also a list. The subclass objects are created "on-demand" and I want to have an overview what was created. My workaround for now is to create a new vector in the global environment and update it with :
if (exists("global_names_list")) global_names_list <<- unique(rbind(global_names_list, some_names)) else global_names_list <<- some_names
This is probably not the best way, but it is a way:
my_list <- list(a = 1, b = "two", c = "set outside")
my_function <- function(x = 1, y = 2, parent_object_name = "my_list"){
z <- x+y
some_names <- "updated inside"
lst <- get(parent_object_name)
lst$c <- some_names
assign(parent_object_name, lst, envir = .GlobalEnv)
return(z)
}
my_function()
#> [1] 3
#check
my_list
#> $a
#> [1] 1
#>
#> $b
#> [1] "two"
#>
#> $c
#> [1] "updated inside"