Fabien Fivaz
2014-Dec-15 17:28 UTC
[R] No visible bindings and assignement to the global environment
Hi everyone, I'm sure this question has been asked before, but I'm unable to find a definitive answer (if there is any). I've been trying to put back to CRAN a package (grasp-r). The package uses many functions that share a lot of common variables. For instance, a model call is created by the first function and then used through all the modeling process, some functions change it with : /assign("MODELCALL", MODELCALL, envir = .GlobalEnv)/ some just use it without being explicitely called in the function arguments. The assignement is explicitely against the CRAN policies (Do not alter the user's workspace). The use of variables raises a warning when building the package : "no visible binding for global variable ?MODELCALL?". BTW, the old school "double" assignement /MODELCALL <<- MODELCALL/ works but raises a similar warning "no visible binding for '<<-' assignment to ?MODELCALL?" And I understand that it is also against CRAN policies to use the double assignement. Many user groups, examples et al. point to R environments. I could create a new.env() in the first function (initializing function), and assign all subsequent variables to it. Something like / /dummy<-function (a) // //{// // dummy.env <- new.env()// // assign("a", a, envir=dummy.env)// // return(dummy.env)// //}/ / and a call_that_variable_back function :/ /dummy2<-function () // //{// // b<-get("a",envir=dummy.env)// // b// //}// / /It works, except that I have to put a enormous sign saying : don't call your env anything else than dummy.env... What do you use ? Is there a best practice for that type of problem ? Thanks in advance for your help, best wishes Fabien -- Fabien Fivaz Centre suisse de cartographie de la faune Passage Max.-Meuron 6 CH - 2000 Neuch?tel Switzerland Tel. +41 32 725 72 57 fabien.fivaz at unine.chv /", a, envir=dummy.env)// // return(dummy.env)// //}/ and a call_that_variable_back function : /dummy2<-function () // //{// // b<-get("b",envir=dummy.env)// // b// //}// / It works, except that I have to put a enormous sign saying : don't call your env anything else than dummy.env... What do you use ? Is there a best practice for that type of problem ? Thanks in advance for your help, best wishes Fabien -- Fabien Fivaz Centre suisse de cartographie de la faune Passage Max.-Meuron 6 CH - 2000 Neuch?tel Switzerland Tel. +41 32 725 72 57 fabien.fivaz at unine.chv [[alternative HTML version deleted]]
Duncan Murdoch
2014-Dec-15 18:47 UTC
[R] No visible bindings and assignement to the global environment
On 15/12/2014 12:28 PM, Fabien Fivaz wrote:> Hi everyone, > > I'm sure this question has been asked before, but I'm unable to find a > definitive answer (if there is any). I've been trying to put back to > CRAN a package (grasp-r). The package uses many functions that share a > lot of common variables. For instance, a model call is created by the > first function and then used through all the modeling process, some > functions change it with : > > /assign("MODELCALL", MODELCALL, envir = .GlobalEnv)/ > > some just use it without being explicitely called in the function > arguments. The assignement is explicitely against the CRAN policies (Do > not alter the user's workspace). The use of variables raises a warning > when building the package : "no visible binding for global variable > ?MODELCALL?". > > BTW, the old school "double" assignement > > /MODELCALL <<- MODELCALL/ > > works but raises a similar warning "no visible binding for '<<-' > assignment to ?MODELCALL?" And I understand that it is also against CRAN > policies to use the double assignement. > > Many user groups, examples et al. point to R environments. I could > create a new.env() in the first function (initializing function), and > assign all subsequent variables to it. Something like > / > /dummy<-function (a) // > //{// > // dummy.env <- new.env()// > // assign("a", a, envir=dummy.env)// > > // return(dummy.env)// > //}/ > > / and a call_that_variable_back function :/ > > /dummy2<-function () // > //{// > // b<-get("a",envir=dummy.env)// > // b// > //}// > / > /It works, except that I have to put a enormous sign saying : don't call > your env anything else than dummy.env... > > What do you use ? Is there a best practice for that type of problem ?It's not clear to me from your description how many of these environments you want. Will a user potentially have more than one of them? If so, then create it in the first call, and pass it explicitly to all other functions. For example, makeit <- function() new.env(parent=emptyenv()) fn1 <- function(env, ... ) { # get stuff from env using env$a, etc. } fn2 <- function(env, ...) { # ditto } So your user would do something like this: env1 <- makeit() # create the first one fn1(env1, ...) # use it env2 <- makeit() # create another fn1(env2, ...) # use it fn1(env1, ...) # use the first one again On the other hand, maybe it only makes sense for one of these to ever exist. Then you should create one for the package, and just use that. For example, env <- new.env(parent = emptyenv()) fn1 <- function(...) { # get stuff from env using env$a, etc. } fn2 <- function(...) { # ditto } Users just call fn1 and fn2, and never need to even know about env. Duncan Murdoch
Fabien Fivaz
2014-Dec-15 21:02 UTC
[R] No visible bindings and assignement to the global environment
Thanks for the quick answer. Your second guess was right, I only need one environment. I learned one thing: I can create a .R file in my package that is NOT a function. Something that contains just dummyEnv <- new-env(parent=emptyenv()) And it works! Thanks again Le 15. 12. 14 19:47, Duncan Murdoch a ?crit :> On 15/12/2014 12:28 PM, Fabien Fivaz wrote: >> Hi everyone, >> >> I'm sure this question has been asked before, but I'm unable to find a >> definitive answer (if there is any). I've been trying to put back to >> CRAN a package (grasp-r). The package uses many functions that share a >> lot of common variables. For instance, a model call is created by the >> first function and then used through all the modeling process, some >> functions change it with : >> >> /assign("MODELCALL", MODELCALL, envir = .GlobalEnv)/ >> >> some just use it without being explicitely called in the function >> arguments. The assignement is explicitely against the CRAN policies (Do >> not alter the user's workspace). The use of variables raises a warning >> when building the package : "no visible binding for global variable >> ?MODELCALL?". >> >> BTW, the old school "double" assignement >> >> /MODELCALL <<- MODELCALL/ >> >> works but raises a similar warning "no visible binding for '<<-' >> assignment to ?MODELCALL?" And I understand that it is also against CRAN >> policies to use the double assignement. >> >> Many user groups, examples et al. point to R environments. I could >> create a new.env() in the first function (initializing function), and >> assign all subsequent variables to it. Something like >> / >> /dummy<-function (a) // >> //{// >> // dummy.env <- new.env()// >> // assign("a", a, envir=dummy.env)// >> >> // return(dummy.env)// >> //}/ >> >> / and a call_that_variable_back function :/ >> >> /dummy2<-function () // >> //{// >> // b<-get("a",envir=dummy.env)// >> // b// >> //}// >> / >> /It works, except that I have to put a enormous sign saying : don't call >> your env anything else than dummy.env... >> >> What do you use ? Is there a best practice for that type of problem ? > > It's not clear to me from your description how many of these > environments you want. Will a user potentially have more than one of > them? If so, then create it in the first call, and pass it explicitly > to all other functions. For example, > > makeit <- function() new.env(parent=emptyenv()) > > fn1 <- function(env, ... ) { # get stuff from env using env$a, etc. } > fn2 <- function(env, ...) { # ditto } > > So your user would do something like this: > > env1 <- makeit() # create the first one > fn1(env1, ...) # use it > > env2 <- makeit() # create another > fn1(env2, ...) # use it > > fn1(env1, ...) # use the first one again > > On the other hand, maybe it only makes sense for one of these to ever > exist. Then you should create one for the package, > and just use that. For example, > > env <- new.env(parent = emptyenv()) > > fn1 <- function(...) { # get stuff from env using env$a, etc. } > fn2 <- function(...) { # ditto } > > Users just call fn1 and fn2, and never need to even know about env. > > Duncan Murdoch-- Fabien Fivaz Centre suisse de cartographie de la faune Passage Max.-Meuron 6 CH - 2000 Neuch?tel Switzerland Tel. +41 32 725 72 57 fabien.fivaz at unine.ch