Skip to contents


library(saferDev)


Datasets

# Function with TRUE and FALSE written in full.
fun1 <- function(x){
    if(x == TRUE){
        base::return(base::mean(x = 1:3, na.rm = FALSE))
    }
}
# Function with T and F used as values.
fun2 <- function(x){
    if(x == T){
        base::return(base::mean(x = 1:3, na.rm = F))
    }
}


Datasets info

fun1 # Function.
## function (x) 
## {
##     if (x == TRUE) {
##         base::return(base::mean(x = 1:3, na.rm = FALSE))
##     }
## }
fun2 # Function.
## function (x) 
## {
##     if (x == T) {
##         base::return(base::mean(x = 1:3, na.rm = F))
##     }
## }


Argument x

# Test if TRUE and FALSE are written in full in fun1.
# Here everything is fine.
true_false_check(x = fun1)
## 
## 
## AFTER RUNNING saferDev::true_false_check().
## INSIDE fun1(), EVERYTHING SEEMS CLEAN.
## NULL
# Here T and F are used.
true_false_check(x = fun2)
## 
## 
## 
## INSIDE fun2(), SOME SYMBOLS T OR F MUST BE WRITTEN TRUE OR FALSE:
## 
## LINE SYMBOL      CODE
## 3    T       if (x == T) {
## 4    F       base::return(base::mean(x = 1:3, na.rm = F))
## 
## MODIFIED FUNCTION RETURNED BY return().
## function (x) 
## {
##     if (x == TRUE) {
##         base::return(base::mean(x = 1:3, na.rm = FALSE))
##     }
## }
## <environment: 0x55e5b1596328>
# The package association of the function calls is not checked: the bare mean() stays unchanged,
# and only the T is replaced by TRUE (run colons_check() separately for the package association).
fun3 <- function(x){ if(x == T){ mean(x = 1:3) } }
true_false_check(x = fun3)
## 
## 
## 
## INSIDE fun3(), SOME SYMBOLS T OR F MUST BE WRITTEN TRUE OR FALSE:
## 
## LINE SYMBOL      CODE
## 3    T       if (x == T) {
## 
## MODIFIED FUNCTION RETURNED BY return().
## function (x) 
## {
##     if (x == TRUE) {
##         mean(x = 1:3)
##     }
## }
## <environment: 0x55e5aec52860>


Argument safer_check

# Safer checkings are performed before main code running.
true_false_check(
    x = fun1, 
    safer_check = TRUE
)
## 
## 
## AFTER RUNNING saferDev::true_false_check().
## INSIDE fun1(), EVERYTHING SEEMS CLEAN.
## NULL


Argument lib_path

# The "NOTGOOD" path does not exists.
true_false_check(
    x = fun1,  
    lib_path = "NOTGOOD"
)
## Error:
## ! 
## 
## ================
## 
## ERROR IN saferDev::true_false_check().
## 
## THE DIRECTORY PATH INDICATED IN THE lib_path ARGUMENT DOES NOT EXIST:
## NOTGOOD
## 
## ================


Argument error_text

# Add a text in error messages returned by true_false_check().
true_false_check(
    x = fun1, 
    lib_path = "NOTGOOD", 
    error_text = " === TEXT ADDED ==="
)
## Error:
## ! 
## 
## ================
## 
## ERROR IN saferDev::true_false_check() === TEXT ADDED ===
## 
## THE DIRECTORY PATH INDICATED IN THE lib_path ARGUMENT DOES NOT EXIST:
## NOTGOOD
## 
## ================


Arguments export and out_path: return or export the corrected function

# The corrected function is returned (NULL if nothing has to be corrected).
fun2_safer <- true_false_check(x = fun2)
## 
## 
## 
## INSIDE fun2(), SOME SYMBOLS T OR F MUST BE WRITTEN TRUE OR FALSE:
## 
## LINE SYMBOL      CODE
## 3    T       if (x == T) {
## 4    F       base::return(base::mean(x = 1:3, na.rm = F))
## 
## MODIFIED FUNCTION RETURNED BY return().
fun2_safer # T replaced by TRUE, F replaced by FALSE.
## function (x) 
## {
##     if (x == TRUE) {
##         base::return(base::mean(x = 1:3, na.rm = FALSE))
##     }
## }
## <environment: 0x55e5b28a55e8>
# And it passes the check.
true_false_check(x = fun2_safer)
## 
## 
## AFTER RUNNING saferDev::true_false_check().
## INSIDE fun2_safer(), EVERYTHING SEEMS CLEAN.
## NULL
# Export the corrected function into the fun2_safer.R file, here in a new temporary folder.
# out_path = "." (default) is the R working directory.
# An existing file is never overwritten (an error is returned instead).
tempo_dir <- base::tempfile(pattern = "dir", tmpdir = base::tempdir(), fileext = "")
base::dir.create(path = tempo_dir, showWarnings = TRUE, recursive = FALSE, mode = "0777")
true_false_check(
    x = fun2,
    export = TRUE,
    out_path = tempo_dir
)
## 
## 
## 
## INSIDE fun2(), SOME SYMBOLS T OR F MUST BE WRITTEN TRUE OR FALSE:
## 
## LINE SYMBOL      CODE
## 3    T       if (x == T) {
## 4    F       base::return(base::mean(x = 1:3, na.rm = F))
## MODIFIED CODE EXPORTED IN:
## /tmp/RtmpwicErU/dir19fa2f6917af/fun2_safer.R
# base::source() of this file recreates the corrected function, named fun2_safer.
base::readLines(con = base::file.path(tempo_dir, "fun2_safer.R", fsep = "/"))
## [1] "fun2_safer <- function (x) "                             
## [2] "{"                                                       
## [3] "    if (x == TRUE) {"                                    
## [4] "        base::return(base::mean(x = 1:3, na.rm = FALSE))"
## [5] "    }"                                                   
## [6] "}"


All the arguments

true_false_check(
    x = fun1, # function name to test.
    export = FALSE, # write the corrected function into a .R file instead of returning it?
    out_path = ".", # folder where to write the file (used only if export = TRUE).
    safer_check = TRUE, # perform some "safer" checks (see https://github.com/safer-r)?
    lib_path = NULL, # where the required packages are if not in the default directories.
    error_text = "" # add information in error messages returned by the function.
)
## 
## 
## AFTER RUNNING saferDev::true_false_check().
## INSIDE fun1(), EVERYTHING SEEMS CLEAN.
## NULL


Sophisticated example

# T and F used as names are not reported: they are user-defined objects.
fun4 <- function(x){
    df <- base::data.frame(T = 1:2, stringsAsFactors = FALSE)
    y <- df$T # column named T
    z <- base::list(F = 3) # argument named F
    base::return(y)
}
true_false_check(x = fun4)
## 
## 
## AFTER RUNNING saferDev::true_false_check().
## INSIDE fun4(), EVERYTHING SEEMS CLEAN.
## NULL
# If T is defined in the function, its uses are not reported.
fun5 <- function(x){
    T <- 2
    base::return(x + T)
}
true_false_check(x = fun5)
## 
## 
## AFTER RUNNING saferDev::true_false_check().
## INSIDE fun5(), EVERYTHING SEEMS CLEAN.
## NULL
# Strings and comments are ignored.
fun6 <- function(x){
    base::return("T") # F
}
true_false_check(x = fun6)
## 
## 
## AFTER RUNNING saferDev::true_false_check().
## INSIDE fun6(), EVERYTHING SEEMS CLEAN.
## NULL