[R] No visible bindings and assignement to the global environment

Duncan Murdoch murdoch.duncan at gmail.com
Mon Dec 15 19:47:20 CET 2014


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



More information about the R-help mailing list