I am working on a function to basically grab arguments from inside a function. It works as expected, but when I try and transport the result, I have an envir
in the list. It outputs fine via dput
, but I CANNOT transport it.
> test(iris)
list(envir = <environment>, call = test(iris), fn.info = list(
fn = "test", dot.keys = NULL, dot.vals = NULL, params = list(
df = "iris"), map = list(df = "iris"), formals = list(
df = "--EMPTY--")))
As you can see, the INTERNALS grab the fn
function name, and function parameters. One element captured is the envir
which is simple to reproduce as follows:
dput( (envir = environment()) );
The list at least TRAPPED the environment, but when I try and paste it back into a session, I get an error:
> x = list(envir = <environment>, call = test(iris), fn.info = list(
Error: unexpected '<' in "x = list(envir = <"
> fn = "test", dot.keys = NULL, dot.vals = NULL, params = list(
Error: unexpected ',' in " fn = "test","
> df = "iris"), map = list(df = "iris"), formals = list(
Error: unexpected ')' in " df = "iris")"
> df = "--EMPTY--")))
Error: unexpected ')' in " df = "--EMPTY--")"
Ideally, I would like to pair of functions that would cast it to/from envir as a string, so I can transport it.
Question: How to transport an environment via dput?
env.toString(envir) {}
env.fromString(envir) {}
The above represents my current roadmap, but I am open to suggestions. I have tried as.character
, as.raw
, as.hexmode
... I believe deparse
internally will work, but that will not enable me to recover the environment as an object without the propose env.fromString
CodePudding user response:
Perhaps you could use ls()
to get the names of all objects in the environment, and then put their names and values in a list, then reconstruct an environment from that list with list2env()
... Something like:
x <- new.env()
x$foo <- 1:3
xnames <- ls(envir = x)
xlist <- lapply(xnames, function(y) {
z <- x[[y]]
if (!inherits(z, 'environment'))
return(z)
})
names(xlist) <- xnames
dput(list(my_env = xlist))
#> list(my_env = list(foo = 1:3))
a_list <- list(my_env = list(foo = 1:3))
x2 <- list2env(a_list$my_env)
print(x2$foo)
#> [1] 1 2 3
CodePudding user response:
If you just need to remove the items from a list that are an environment you can just iterate over the list remove the elements that inherit from 'environment'
x <- list(a = new.env(), b = "foo")
dput(x[-sapply(x, inherits, 'environment')])
#> list(b = "foo")