From 52a8aa7026b84440b217ceb7106c4a029b9ef843 Mon Sep 17 00:00:00 2001 From: Marco Colombo Date: Wed, 22 Oct 2025 21:59:48 +0200 Subject: [PATCH] Note potential danger if argument can be NA in scalar_in_linter(). --- R/scalar_in_linter.R | 8 ++++++-- man/scalar_in_linter.Rd | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/R/scalar_in_linter.R b/R/scalar_in_linter.R index 0f0828d78f..6c9d26d613 100644 --- a/R/scalar_in_linter.R +++ b/R/scalar_in_linter.R @@ -1,7 +1,10 @@ #' Block usage like x %in% "a" #' #' `vector %in% set` is appropriate for matching a vector to a set, but if -#' that set has size 1, `==` is more appropriate. +#' that set has size 1, `==` is more appropriate. However, if `vector` has +#' also size 1 and can be `NA`, the use of `==` should be accompanied by extra +#' protection for the missing case (for example, `isTRUE(NA == "arg")` or +#' `!is.na(x) && x == "arg"`). #' #' `scalar %in% vector` is OK, because the alternative (`any(vector == scalar)`) #' is more circuitous & potentially less clear. @@ -46,7 +49,8 @@ scalar_in_linter <- function(in_operators = NULL) { in_op <- xml_find_chr(bad_expr, "string(SPECIAL)") lint_msg <- paste0( "Use comparison operators (e.g. ==, !=, etc.) to match length-1 scalars instead of ", in_op, ". ", - "Note that comparison operators preserve NA where ", in_op, " does not." + "Note that if x can be NA, x == 'arg' is NA whereas x ", in_op, " 'arg' is FALSE, ", + "so consider extra protection for the missing case in your code." ) xml_nodes_to_lints( diff --git a/man/scalar_in_linter.Rd b/man/scalar_in_linter.Rd index 1773c699f8..6b8db47bea 100644 --- a/man/scalar_in_linter.Rd +++ b/man/scalar_in_linter.Rd @@ -12,7 +12,10 @@ e.g. \code{{data.table}}'s \verb{\%chin\%} operator.} } \description{ \code{vector \%in\% set} is appropriate for matching a vector to a set, but if -that set has size 1, \code{==} is more appropriate. +that set has size 1, \code{==} is more appropriate. However, if \code{vector} has +also size 1 and can be \code{NA}, the use of \code{==} should be accompanied by extra +protection for the missing case (for example, \code{isTRUE(NA == "arg")} or +\code{!is.na(x) && x == "arg"}). } \details{ \code{scalar \%in\% vector} is OK, because the alternative (\code{any(vector == scalar)})