Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent partial argument matching

Tags:

r

I have an R function:

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

I am now extending the function, allowing a set of arbitrary extra arguments:

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

How may I disable partial argument matching on the base parameter? I cannot put the ... before base='' because I'd like to maintain backwards compatibility of the function (it is often called as myFunction('somevalue', 'someothervalue') without base being explicitly named).

I got stung by calling my function like so:

myFunc(x, b='foo')

I want this to mean base='', b='foo', but R uses partial matching and assumes base='foo'.

Is there some code I can insert in myFunc to determine what argument names were passed in and only match the exact "base" to the base parameter, otherwise grouping it in as part of the ...?

like image 450
mathematical.coffee Avatar asked Mar 07 '13 06:03

mathematical.coffee


2 Answers

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] ""
like image 162
Josh O'Brien Avatar answered Oct 11 '22 10:10

Josh O'Brien


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)) .

}
like image 44
mathematical.coffee Avatar answered Oct 11 '22 08:10

mathematical.coffee