6

Following your recommendations (or trying to do it, at least), I have tried some options, but the problem remains, so there must be something I am missing.

I have included a more complete code

setwd("C:/naapp")
#' @import utils 
#' @import devtools 

I have tried with and without using suppressForeignCheck

if(getRversion() >= "2.15.1"){

  utils::globalVariables(c("eleven"))
  utils::suppressForeignCheck(c("eleven"))

  }


myFunctionSum <- function(X){print(X+eleven)}

myFunctionMul <- function(X){print(X*eleven)}

myFunction11 <- function(X){
  assign("eleven",11,envir=environment(myFunctionMul))
  }

maybe I should use a particular environment?

package.skeleton(name = "myPack11", list=ls(),
                 path = "C:/naapp", force = TRUE,
                 code_files = character())

I remove the "man" directory from the directory myPack11, otherwise I would get an error because the help files are empty. I add the imports utils, and devtools to the descrption

Then I run check

devtools::check("myPack11")

And I still get this note

#checking R code for possible problems ... NOTE
#myFunctionMul: no visible binding for global variable 'eleven'
#myFunctionSum: no visible binding for global variable 'eleven'
#Undefined global functions or variables:eleven

I have tried also to make an enviroment, combining Tomas Kalibera's suggetion and an example I found in the Internet.

myEnvir <- new.env()
myEnvir$eleven <- 11

etc In this case, I get the same note, but with "myEnvir", instead of "eleven"


First version of the question

I trying to use "globalVariables" from the package utils. I am building an interface in R and I am planning to submit to CRAN. This is my first time, so, sorry if the question is very basic.I have read the help and I have tried to find examples, but I still don't know how to use it.

I have made a little silly example to ilustrate my question, which is: Where do I have to place this line exactly?:

if(getRversion() >= "2.15.1"){utils::globalVariables("eleven")}

My example has three functions. myFunction11 creates the global variable "eleven" and the other two functions manipulate it. In my real code, I cannot use arguments in the functions that are called by means of a button. Consider that this is just a silly example to learn how to use globalVariables (to avoid binding notes).

myFunction11 <- function(){

  assign("eleven",11,envir=environment(myFunctionSum))

}

myFunctionSum <- function(X){

  print(X+eleven)

}

myFunctionMul <- function(X){

  print(X*eleven)

}

Thank you in advance

Waldir Leoncio
  • 10,853
  • 19
  • 77
  • 107
Marina
  • 369
  • 3
  • 9
  • 6
    One _great_ way to discover this might be: https://github.com/search?q=utils%3A%3AglobalVariables&type=Code&utf8=✓ – hrbrmstr Oct 26 '16 at 01:42

3 Answers3

9

I thought that the file globals.R would be automatically generated when using globalsVariables. The problem was that I needed to create the package skeleton, then create the file globals.R, add it to the R directory in the package and check the package.

So, I needed to place this in a different file:

#' @import utils 
utils::globalVariables(c("eleven"))

and save it

Marina
  • 369
  • 3
  • 9
5

The documentation clearly says:

 ## In the same source file (to remind you that you did it) add:
 if(getRversion() >= "2.15.1")  utils::globalVariables(c(".obj1", "obj2"))

so put it in the same source file as your functions. It can go in any of your R source files, but the comment above recommends you put it close to your code. Looking at a bunch of github packages reveals another common pattern is to have a globals.R function with it in, but this is probably a bad idea. If you later remove the global from your package but neglect to update globals.R you could mask a problem. Putting it right close to the functions that use it will hopefully remind you when you edit those functions.

Make sure you put it outside any function definitions in the file, or it won't get seen.

Spacedman
  • 92,590
  • 12
  • 140
  • 224
  • 2
    It specifically has to be *under* the function definition. You get an immediate warning if it's above it: `@title Missing name` (I guess it messes with the roxygenizing if the executable code doesn't begin with either a function definition or a `NULL`?). – DHW Mar 11 '20 at 16:41
  • 1
    @DHW this was really helpfull! thank you! – sahuno Aug 01 '23 at 16:13
4

You cannot modify bindings in a package namespace once the package is loaded (and namespace sealed, and bindings locked). The check tool helps you to spot violations of this restriction, so you find out about the problem when checking the package rather than while running it. globalVariables is just a call to silence check when looking for these violations, which is undesirable in almost all cases. If you really need mutable state in a package, you can create a new environment (using new.env) and bind it to an (unexported) "global" variable in your namespace. This binding will be locked, but this is ok, because in R you can change an environment in place (add/remove elements, effectively modifying the elements).

The best situation is however when you can keep all mutable state in user objects (passed in as arguments into functions, and their modified versions returned as output values of functions).

Tomas Kalibera
  • 1,061
  • 9
  • 13