How to add features to an existing environment

Is it possible to use env() as a replacement for namespaces and how do you check if the environment already exists before adding functions to it?

This is related to this question, and Brendan's suggestion How to organize large R programs? I understand Dirk's point in this matter, however, for development, it is sometimes impractical to put functions in packages.

EDIT: The idea is to simulate namespaces between files and therefore be able to load different files independently of each other. If the file has been preloaded, then the environment does not need to be created, it is simply added to.

Thanks for the ideas.

EDIT: So, presumably, this code below will be equivalent to namespaces in other languages: -

  # how to use environment as namespaces # file 1 # equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) { e <- new.env(parent=baseenv()) } e$f1 <- function(x) {1} # file 2 # equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) { e <- new.env(parent=baseenv()) } e$f2 <- function(x) {2} 
+6
source share
3 answers

Yes, you can for the most part. Each function has an environment and that is where it looks for other functions and global variables. Using your own environment, you are in complete control of this.

Typically, functions are also assigned to the environment (by assigning them a name), and usually the two environments are the same, but not always. In a package, the namespace environment is used for both, but then the (different) package environment on the search path also has the same (exported) functions defined. So the environment is different.

 # this will ensure only stats and packages later on the search list are searched for # functions from your code (similar to import in a package) e <- new.env(parent=as.environment("package:stats")) # simple alternative if you want access to everything # e <- new.env(parent=globalenv()) # Make all functions in "myfile.R" have e as environment source("myfile.R", local=e) # Or change an existing function to have a new environment: e$myfunc <- function(x) sin(x) environment(e$myfunc) <- e # Alternative one-liner: e$myfunc <- local(function(x) sin(x), e) # Attach it if you want to be able to call them as usual. # Note that this creates a new environment "myenv". attach(e, name="myenv") # remove all temp objects rm(list=ls()) # and try your new function: myfunc(1:3) # Detach when it time to clean up or reattach an updated version... detach("myfile") 

In the above example, e corresponds to the namespace, and the attached "myenv" corresponds to the package environment (for example, "package: statistics" on the search path).

+5
source

Namespaces are environments, so you can use exactly the same mechanism. Since R uses a lexical definition, the parent element of the environment determines what the function sees (for example, how free variables are bound). And just like a namespace, you can attach environments and search for them.

So, to create a new β€œmanual namespace”, you can use something like

 e <- new.env(parent=baseenv()) # use local(), sys.source(), source() or e$foo <- assignment to populate it, eg local({ f <- function() { ... } #... }, e) attach(e, name = "mySuperNamespace") 

Now it loads and attaches in the same way as a namespace, so you can use f in the same way as in a namespace. Namespaces use another parent environment to allow imports β€” you can do this too if you want. If you need to check your cool environment, just check the search path, for example "mySuperNamespace" %in% search() . If you need a real environment, use as.environment("mySuperNamespace")

+4
source

You can verify that environments exist in the same way as any other variable.

 e <- new.env() exists("e") && is.environment(e) 
+2
source

Source: https://habr.com/ru/post/906851/


All Articles