NEWS
saferDev 3.0.0
- Backbone v21.1: the invented
x argument names (absent from the called function signature, for instance base::any(x = ...), base::all(x = ...), base::sum(x = ...), base::order(x = ...)) are removed from all the function calls.
- curly_bracket_check(): new function. Verifies that all the bodies of the if, else, for, while, repeat and function are delimited by curly brackets {}. The corrected function is returned, or exported with export = TRUE.
- for_loop_nb_check(): new function. Verifies that the sequence expression of every for loop is written with hard numbers (like 1:3) or with a single seq_len() or seq_along() call. Otherwise (like 1:length(x)), a checking line is added before the loop, issuing a warning at execution if the sequence is empty, contains NA or infinite values, has a single value, or, for numeric sequences, has only negative values or is decreasing. The corrected function is returned, or exported with export = TRUE.
- lambda_check(): new function. Verifies that the lambda functions written with the shorthand (x) are all written with the standard function(x) writing. The \ token of each reported lambda writing is replaced by function. Warning: the (x) writing is only kept in the code of a function carrying its source references (attribute srcref), so that compiled or loaded package functions cannot be checked. The corrected function is returned, or exported with export = TRUE.
- super_assign_check(): new function. Verifies that the superassignment operators <<- and ->> are not used in a function. An error is returned with the table of the lines with problems if any, because what these operators modify depends on the environments where the function is defined and called (difficult to guess what the writer had in mind, nothing can be corrected automatically). NULL is returned invisibly otherwise.
- all_args_here() and colons_check(): a pre-check by lambda_check() is now performed: if some lambda functions written with the (x) shorthand are detected in the code of the submitted function, an error asking to run saferDev::lambda_check() first is returned.
- true_false_check(): new function. Verifies that TRUE and FALSE are always written in full when used as values, and never abbreviated as T or F. The corrected function (T replaced by TRUE and F replaced by FALSE) is returned, or exported with export = TRUE.
- colons_check(): the missing package attributions of the basic R functions are now added: the corrected function is returned, or exported with the new export and out_path arguments. These two arguments are placed before safer_check, lib_path and error_text (breaking change for calls using argument positions).
- all_args_here(): the missing arguments are now added: the corrected function is returned, or exported with the new fun_export argument. The former export argument is renamed table_export (breaking change). The table of the missing arguments is returned as a message (table_export = FALSE) or exported (table_export = TRUE). The modified function is returned (fun_export = FALSE, whatever table_export) or exported (fun_export = TRUE).
- curly_bracket_check(), for_loop_nb_check(), lambda_check(), true_false_check(), colons_check() and all_args_here(): the exported file is named _safer.R and written in out_path (default ".", the R working directory). It contains _safer <- function(...) ..., so that base::source() recreates the corrected function. out_path cannot be NULL nor an empty string. An error is returned if the file already exists, or if the tested function is not designated by its name. A "MODIFIED CODE EXPORTED IN" message gives the file path, and NULL is returned (invisibly).
- arg_check(): output component object.name renamed object_name (breaking change).
- arg_check(): with prop = TRUE, the class, typeof and mode arguments must be NULL, otherwise an error is returned (breaking change). prop = TRUE already checks that the tested object is of type "double" with values between -1 and 1 (neg_values = TRUE, default), or between 0 and 1 (neg_values = FALSE). neg_values = FALSE is now allowed with prop = TRUE, without typeof or mode (breaking change: with prop = TRUE alone, negative values down to -1 are now accepted; add neg_values = FALSE to keep the former 0 to 1 range). To also check the class of the object (a matrix for instance), use a second arg_check() call with prop = FALSE.
- colons_check() and all_args_here(): the "in" symbol is now skipped during code parsing, which prevents spurious parsing problems with for(j in (n - 1L):2L) writings.
- all_args_here(): an incoherent arg_full_names argument no longer causes a raw crash, but a proper internal error.
- all_args_here(): the modified function (returned, or exported with fun_export = TRUE) now keeps the comments and the indentation of the submitted function (when it carries its source references), instead of the normalized code without comments. A proposal is not applied (and is listed in the CORRECTIONS NOT APPLIED message) when the corrected call contains a string with consecutive spaces, which were formerly silently collapsed. The CORRECTIONS NOT APPLIED message no longer replaces the ARGUMENTS ARE MISSING message.
- all_args_here(): safer-r rules about empty argument values. A default value that cannot be copied into the call (depending on another argument, like envir = as.environment(pos) in utils::getFromNamespace(), on the internal environment of the function, or on the frame of evaluation, like parent.frame()) is now proposed with an empty value (like envir = ), instead of being copied (which changed its evaluation environment). An argument with no default value is now proposed with an empty value (like base::.libPaths(new = , include.site = TRUE)) when no argument is written, instead of returning a writing error. Proposals with empty values are now applied to the modified function. A new ARGUMENTS WITH EMPTY VALUE message lists the arguments written or proposed with an empty value, with their default value. An argument placed after ... in the function definition no longer takes a value written without argument name.
- all_args_here(): the ARGUMENTS WITH EMPTY VALUE message no longer lists the arguments already written with an empty value in the code (like base::.libPaths(new = , include.site = TRUE) or utils::getFromNamespace(x = "a", ns = "b", pos = , envir = )): they are accepted as is. Only the empty values proposed by all_args_here() are listed.
- all_args_here(): an argument written with a partial name (e.g., dig for digits) is now completed in the STATUS proposal and in the modified function, instead of a warning message (only for the arguments before ..., as in R: a partial name after ... is an argument of ..., no longer wrongly flagged). An argument written with an empty value (e.g., safer_check = ) gets its default value if it can be copied, and remains empty otherwise (no default value, or a default value depending on another argument or on the frame of evaluation).
- colons_check(): the modified function (returned, or exported with export = TRUE) now keeps the comments and the indentation of the submitted function: the package attributions are inserted in the printed code of the submitted function, and no longer in the analyzed code (comments removed and multiple spaces collapsed). Comments are only available when the submitted function carries its source references (attribute srcref).
- curly_bracket_check(): the modified function (returned, or exported with export = TRUE) now keeps the comments and the indentation of the submitted function, instead of the deparsed code (comments removed and code reindented). Comments are only available when the submitted function carries its source references (attribute srcref).
- all_args_here(): a string ending with an escaped backslash (like "\\") no longer makes the rest of the line considered as inside quotes, which caused spurious reports or an INTERNAL ERROR 3 of .fun_args_pos().
- R (>= 4.6.0) is now required (it was R (>= 4.5.0) in saferDev 2.0.0).
- all_args_here(), colons_check(), env_check(), get_message() and report(): the lib_path argument is now always checked and used, whatever the value of safer_check, as in the other functions of the package (safer-r backbone v21.2: lib_path is used outside the safer_check checkings, for instance in the saferDev::arg_check() calls). An incorrect lib_path now returns an error even with safer_check = FALSE. In arg_check(), lib_path is still checked only when safer_check is TRUE, because lib_path is only used inside the safer_check checkings of arg_check() (backbone v21.2), and arg_check() is called thousands of times with safer_check = FALSE inside the other functions of the package (checking lib_path at each call multiplies their execution time by about five). The documentation of the safer_check argument is updated accordingly: the lib_path check is no longer listed among the checkings performed with safer_check = TRUE, except in arg_check().
- all_args_here(): the returned modified function now keeps the environment of the submitted function. It formerly had an internal environment of saferDev as closure environment, so that some of its free variables (e.g., a global object named out or x) were not found where expected.
- colons_check(): a word followed by an opening bracket inside a string containing escaped quotes, like "a \"b\" WORD (c)", is no longer reported as a function written without its package.
- All the functions of the package now follow the safer-r backbone v21.2 (all the sections present, in the backbone order; internal functions fetched in the "escaping CRAN submission NOTE" section; utils::getFromNamespace(pos = -1, envir = ) writing) and pass their own seven code checks: super_assign_check(), lambda_check(), curly_bracket_check(), true_false_check(), for_loop_nb_check(), colons_check() and all_args_here().
saferDev 2.0.0 (2026-10-14)
- arg_check(): new behavior for the class, typeof and mode arguments. Values are now compared exactly (same values, same order) to class(data), typeof(data) and mode(data). Thus, class = "matrix" alone always returns a problem since R 4.0.0 (use class = c("matrix", "array")), class = "factor" alone always returns a problem for ordered factors (use class = c("ordered", "factor")), and class = "vector" is no longer a shortcut for numeric, integer, character, logical, complex or expression classes. In addition, double_as_integer_allowed = TRUE now also rescues class = "integer" when the tested object is a double with zero as modulo.
- All the safer-r functions now check that the ... argument is not used, and that the reserved lib_path, safer_check and error_text arguments are present.
- R (>= 4.5.0) is now required.
saferDev 1.0.0 (2026-06-08)