12 Enumerate possible options

12.1 What’s the pattern?

If the possible values of an argument are a small set of strings, set the default argument to the set of possible values, and then use match.arg() or rlang::arg_match() in the function body. This convention advertises to the user what the possible values, and makes it easy to generate an informative error message for inappropriate inputs.

12.2 What are some examples?

  • In difftime(), units can be any one of “auto”, “secs”, “mins”, “hours”, “days”, or “weeks”.

  • In format(), justify can be “left”, “right”, “center”, or “none”.

  • In trimws(), you can choose which side to remove whitespace from: “both”, “left”, or “right”.

  • In rank(), you can select the ties.method from one of “average”, “first”, “last”, “random”, “max”, or “min”.

  • In RSiteSearch(), you can restrict results to be “functions”, “vignettes”, “views”, or any combination of the three.

12.3 Why is it important?

This convention makes it possible to advertise the possible set of values for an argument. The advertisement happens in the function specification, so you see in tooltips and autocomplete, without having to look at the documentation.

12.4 How do I use it?

To use this technique, set the default value to a character vector, where the first value is the default. Inside the function, use match.arg() or rlang::arg_match() which checks that the value comes from the known good set. This interface pattern is often coupled with an implementation that uses switch().

Take rank(), for example. The heart of its implementation looks like this:

Note that match.arg() will automatically throw an error if the value is not in the set:

It also supports partial matching so that the following code is shorthand for `ties.method = “random”:

I generally believe that partial matching is a bad idea, because it makes code harder to read. rlang::arg_match() is an alternative to match.args() that doesn’t support partial matching. Instead it provides a helpful error message:

12.4.1 How keep defaults short?

This technique is a best used when the set of possible values is short. You can see that it’s already getting unwieldy in rank(). If you have a long list of possibilities, there are two options that you could use from Chapter 14. Unfortunately both approaches have major downsides: