Prevent partial argument matching

Here's an idea:

myFunc <- function(x, .BASE = '', ..., base = .BASE) {
    base
}

## Takes fully matching named arguments       
myFunc(x = "somevalue", base = "someothervalue")
# [1] "someothervalue"

## Positional matching works
myFunc("somevalue", "someothervalue")
# [1] "someothervalue"

## Partial matching _doesn't_ work, as desired
myFunc("somevalue", b="someothervalue")
# [1] ""

The easiest way is to simply set some R options. In particular,

  • warnPartialMatchArgs: logical. If true, warns if partial matching is used in argument matching.
  • warnPartialMatchAttr: logical. If true, warns if partial matching is used in extracting attributes via attr.
  • warnPartialMatchDollar: logical. If true, warns if partial matching is used for extraction by $.

Setting these variables will now raise warnings, that you can turn into errors if you wish.


Just arrived on another way to solve this, prompted by @Hemmo.

Use sys.call() to know how myFunc was called (with no partial argument matching, use match.call for that):

myFunc <- function(x, base='', ...) {
    x <- sys.call() # x[[1]] is myFunc, x[[2]] is x, ...
    argnames <- names(x)
    if (is.null(x$base)) {
        # if x[[3]] has no argname then it is the 'base' argument (positional)
        base <- ifelse(argnames[3] == '', x[[3]], '')
    }
    # (the rest of the `...` is also in x, perhaps I can filter it out by
    #  comparing argnames against names(formals(myFunc)) .

}

Tags:

R