r-lib / rlang

Low-level API for programming with R
https://rlang.r-lib.org
Other
498 stars 136 forks source link

add `check_length()` to `standalone-types-check.R` #1618

Open ateucher opened 1 year ago

ateucher commented 1 year ago

It would be nice to be able to check if a vector is of a required length (exact, min or max). The scalar checkers check_name(), check_string() etc., ensure an object is of length 1, but being able to check length constraints > 1 would be helpful. I could see this being implemented as something like:

check_length(x, ..., length, arg = caller_arg(x), call = caller_env())

where length could be either a scalar integer value to specify an exact required length, or a length 2 vector supplying an allowed range of lengths (which could include -Inf or Inf if only a minimum or maximum length is required).

Alternatively, a length argument could be added to the vector checkers such as check_character() and check_logical().

lionel- commented 1 year ago

I think that makes sense. I'd just put length on the left of ... to avoid the repetition in calls, e.g. check_length(x, length = 3) vs check_length(x, 3). I'm not sure we need to allow for ranges of length though. But sometimes we want to allow multiple lengths when recycling is allowed, e.g. length 1 or length n. So maybe it should rather be length = c(1, n)?

ateucher commented 1 year ago

I hadn't thought about the recycling situation, but it's a good point! I proposed the range to address situations like this, where there is a minimum length required (in this case a character vector with length > 0). I agree that requiring a specific range, or even a maximum length is probably not a common scenario, but requiring a non-empty vector that could be any length >=1 is fairly common. Maybe for that case an allow_empty argument could be added to check_character() etc?

olivroy commented 3 months ago

I think check_character() should have a way to disallow character(0), i.e. length 1 or more.

the use case is that I want to accept NULL (length 0), and character of length 1 or more (not character(0))

I think that allow_empty is confusing since check_string(allow_empty = FALSE) is used to disallow ""