It's frustrating to have to fix issues one by one when the code had all the info to give exhaustive help from the first run.
and1 <- function(a , b) {
stopifnot(is.logical(a), is.logical(b))
a & b
}
and1(0, 1) # nope
#> Error in and1(1, 2): is.logical(a) is not TRUE
# fix it
and1(FALSE, 1) # still not good
#> Error in and1(FALSE, 2): is.logical(b) is not TRUE
# fix again
and1(FALSE, TRUE) # finally works
#> [1] FALSE
We can design complex combination but this looks bad and with more checks it would become very complicated very fast.
and2 <- function(a , b) {
if (!is.logical(a)) {
if (!is.logical(b)) {
stop("\n`a` must be logical\n`b` must be logical")
}
stop("`a` must be logical")
}
if (!is.logical(b)) {
stop("`b` must be logical")
}
stopifnot(is.logical(a), is.logical(b))
a & b
}
and2(1,2)
#> Error in and2(1, 2):
#> `a` must be logical
#> `b` must be logical
What's a good way to do this without the messy code ?
I'd probably make a named logical vector and then check that vector
and1 <- function(a,b){
checks <- c(
"`a` must be logical" = !is.logical(a),
"`b` must be logical" = !is.logical(b)
)
if(any(checks)) {
paste("\n",names(checks[which(checks)]), collapse = "") |>
stop()
}
a & b
}
and1(1,2)
#> Error in and1(1, 2) :
#> `a` must be logical
#> `b` must be logical
(format the error message as desired)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With