Skip to content
Snippets Groups Projects
Select Git revision
  • 8559a6c5eb295f8af6b089ede2e8c891e9eccdfd
  • master default protected
  • v1.7
  • v1.6
  • v1.5
  • v1.4
  • v1.3
  • v1.2
  • v1.1
  • v1.0
10 results

r_debugging_tools.R

Blame
  • Forked from Gael MILLOT / debugging_tools_for_r_dev
    7 commits behind the upstream repository.
    user avatar
    Gael authored
    8559a6c5
    History
    r_debugging_tools.R 5.91 KiB
    ################################################################
    ##                                                            ##
    ##     R DEBUGGING TOOLS v1.2                                  ##
    ##                                                            ##
    ##     Gael A. Millot                                         ##
    ##                                                            ##
    ##     Compatible with R v3.5.1                               ##
    ##                                                            ##
    ################################################################
    
    
    
    str_basic_arg_check_dev <- '
    # AIM:
    # string that check:
    # NULL argument default values
    # arguments without default values
    # arguments with variable as default value (FORBIDDEN)
    # STRING
    function.name <- as.list(match.call(expand.dots=FALSE))[[1]]
    default.arg.list <- formals(fun = sys.function(sys.parent(n = 2))) # list of all the arguments of the function with their default values (not the values of the user !). Use n = 2 when he string has to be evaluated by eval() inside a function. Use n=1 (default) if not evaluation. It seems that ls() as first line of the function provide the names of the arguments (empty, called, etc., or not)
    arg.without.default.value <- sapply(default.arg.list, is.symbol) & sapply(sapply(default.arg.list, as.character), identical, "") # logical to detect argument without default values (these are typeof "symbol" and class "name" and empty character
    name.or.empty.default.val.arg.log <- sapply(default.arg.list, FUN = "class") == "name"
    
    if(length(name.or.empty.default.val.arg.log) != length(arg.without.default.value)){
    stop(paste0("\n\n================\n\nINTERNAL ERROR IN str_basic_arg_check_dev IN ", function.name,". CODE MUST BE MODIFED\n\n================\n\n"))
    }else if(any(name.or.empty.default.val.arg.log & ! arg.without.default.value)){
    cat(paste0("\n\n================\n\nALERT\nDEFAULT VALUE OF ARGUMENT OF ", function.name," MUST NOT BE A VARIABLE (POTENTIAL PROBLEM OF SCOPE)\nTHE CONCERNED ARGUMENTS ARE:\n", paste(names(formals(fun = sys.function(sys.parent(n = 2))))[name.or.empty.default.val.arg.log & ! arg.without.default.value], collapse = "\n"), "\n\n================\n\n"))
    }
    
    cat(paste0("\n\n================================\n\n", function.name," FUNCTION ARGUMENT CHECKING\n\n================================\n"))
    cat(paste0("\n================\nARGUMENTS OF THE FUNCTION ARE (INCLUDING DEFAULT VALUES):\n\n"))
    print(default.arg.list)
    
    if(any(arg.without.default.value)){ # argument names that are empty by default added now because null arguments will not be inserted thenafter
    cat(paste0("\n================\nARGUMENTS WITHOUT DEFAULT VALUES ARE: ", paste(names(default.arg.list)[arg.without.default.value], collapse= " ")))
    }else{
    cat(paste0("\n================\nNO ARGUMENTS WITHOUT DEFAULT VALUES"))
    }
    
    if(any(sapply(default.arg.list, FUN = is.null))){
    cat(paste0("\n================\nNULL ARGUMENTS ARE: ", paste(names(default.arg.list)[sapply(default.arg.list, FUN = is.null)], collapse= " ")))
    }else{
    cat(paste0("\n================\nNO NULL ARGUMENTS"))
    }
    
    if(any( ! sapply(default.arg.list, FUN = is.null))){
    cat(paste0("\n================\nNON NULL ARGUMENTS ARE: ", paste(names(default.arg.list)[ ! sapply(default.arg.list, FUN = is.null)], collapse= " ")))
    }else{
    cat(paste0("\n================\nNO NON NULL ARGUMENTS"))
    }
    
    if(any(sapply(default.arg.list, FUN = is.logical))){
    cat(paste0("\n================\nLOGICAL ARGUMENTS ARE: ", paste(names(default.arg.list)[sapply(default.arg.list, FUN = is.logical)], collapse= " ")))
    }else{
    cat(paste0("\n================\nNO LOGICAL ARGUMENTS"))
    }
    
    if(any(sapply(default.arg.list, FUN = is.na))){
    cat(paste0("\n================\nNA ARGUMENTS ARE: ", paste(names(default.arg.list)[sapply(default.arg.list, FUN = is.na)], collapse= " ")))
    }else{
    cat(paste0("\n================\nNO NA ARGUMENTS"))
    }
    
    cat(paste0("\n================\n\n"))
    # END STRING
    '
    
    str_arg_check_with_fun_check_dev <- '
    # AIM:
    # string that check:
    # which arguments have been checked using fun_check()
    # STRING
    function.name <- as.list(match.call(expand.dots=FALSE))[[1]]
    default.arg.list <- formals(fun = sys.function(sys.parent(n = 2))) # list of all the arguments of the function with their default values (not the values of the user !). Use n = 2 when he string has to be evaluated by eval() inside a function. Use n=1 (default) if not evaluation. It seems that ls() as first line of the function provide the names of the arguments (empty, called, etc., or not)
    if( ! any(ls() %in% "checked.arg.names")){
        cat(paste0("\n\n================\n\nERROR: MISSING checked.arg.names OBJECT. ARGUMENTS MAY HAVE NOT BEEN CHECKED USING fun_check(). SEE THE fun_export_data() FUNCTION FOR THIS KIND OF CHECKING\n\n================\n\n"))
    }
    if( ! find("fun_check") == ".GlobalEnv"){
        cat(paste0("\n\n================\n\nERROR: MISSING fun_check() FUNCTION IN THE GLOBAL ENVIRONMENT. ARGUMENTS MAY HAVE NOT BEEN CHECKED USING fun_check(). SEE THE fun_export_data() FUNCTION FOR THIS KIND OF CHECKING\n\n================\n\n"))
    }
    cat(paste0("\n\n================================\n\n", function.name," FUNCTION ARGUMENT CHECKING USING fun_check()\n\n================================\n"))
    if(any(duplicated(checked.arg.names))){ # for function debbuging
    cat(paste0("\n================\nTHESE ARGUMENTS ARE DUPLICATED IN CHECK USING fun_check(): ", paste(checked.arg.names[duplicated(checked.arg.names)], collapse = " ")))
    }
    if( any(! names(default.arg.list) %in% checked.arg.names)){ # check the correct number of args # for function debbuging # names(default.arg.list) can be replaced by formalArgs("name of the created function")
    cat(paste0("\n================\nTHESE ARGUMENTS HAVE NOT BEEN CHECKED WITH fun_check(): ", paste(names(default.arg.list)[ ! names(default.arg.list) %in% checked.arg.names], collapse = " ")))
    }else{
    cat(paste0("\n================\nALL THE ARGUMENTS HAVE BEEN CHECKED USING fun_check()"))
    }
    cat(paste0("\n================\n\n"))
    # END STRING
    '