Home > Software engineering >  Check if function body references symbols that are not arguments (formals)
Check if function body references symbols that are not arguments (formals)

Time:02-10

I was implementing a long function which takes many arguments and realised that the function body referenced a variable (symbol) which was not an argument (i.e. not a formal contained in the call signature) but the function was failing silently since the variable was present in the global environment. This is of course a common problem for beginners, but also more experienced users on occasion.

Is there a way, either programmatically or via a tool available in a popular UI (e.g. RStudio) to quickly check the modularity of functions?

Of course one can implement unit tests and in general be careful when writing scripts but tests are overkill for functions used only for parts of brief projects and a tool as described would be useful when writing longer / more complicated scripts.

I have extracted out the core idea in the following snippet where the question is effectively: How can the presence of z in the function body of add_three_numbers be quickly, easily and ideally automatically identified?

z <- 2

add_three_numbers <- function(x, y) {
  x   y   z
}

add_three_numbers(1, 2)

For example, I imagined a function that parses the function body and differences a set of the symbols found therein with the list of symbols making up the formal arguments of that function if doing this programmatically, or else a function in RStudio that somehow achieves the same result.

CodePudding user response:

R CMD check will do this for you if your code is in a package. If you're not using a package, you should be. The test uses codetools::findGlobals. For example,

add_three_numbers <- function(x, y) {
  x   y   z
}

codetools::findGlobals(add_three_numbers, merge = FALSE)
#> $functions
#> [1] "{" " "
#> 
#> $variables
#> [1] "z"

Created on 2022-02-09 by the reprex package (v2.0.1.9000)

  • Related