Bug 15654 - WISH/ROBUSTNESS: R CMD check for non-named '...' arguments to NextMethod()
Summary: WISH/ROBUSTNESS: R CMD check for non-named '...' arguments to NextMethod()
Status: NEW
Alias: None
Product: R
Classification: Unclassified
Component: Wishlist (show other bugs)
Version: R-devel (trunk)
Hardware: All All
: P5 enhancement
Assignee: R-core
URL:
Depends on:
Blocks:
 
Reported: 2014-02-03 20:58 UTC by Henrik Bengtsson
Modified: 2014-02-03 20:58 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Henrik Bengtsson 2014-02-03 20:58:16 UTC
RATIONAL:
I don't think there is a single use case where there is a need for passing non-named arguments to NextMethod() via its '...' argument(s).  Instead, I'd argue it's unsafe to do so and when done the bug is often hard to track down and in worst case not even caught (e.g. silently passing the assigning argument values to non-intended arguments).  BTW, I'm not referring to arguments 'generic' and 'object' of NextMethod(), only its '...'.  

For example, calling NextMethod("foo", x, a=1, 2, c=3) passes value '2' by position.  Which argument that will be assigned this value in the end depends on how the generic was called and any previous NextMethod() calls, which is very hard to predict when writing the code.  I doubt the developer does this intentionally.


WISH #1 ("R CMD check"):
NextMethod() is mainly used by package developers and it therefor makes sense to have 'R CMD check' check the above and give a NOTE, a WARNING or an ERROR.


WISH #2 ("run time"):
Since NextMethod() is very rarely called by users, it's of less value to protect against these mistakes at run time, but ignoring overhead, *conceptually* it could be done as:

NextMethod <- function(generic=NULL, object=NULL, ...)
 {
  if (length(args <- list(...)) && (is.null(names <- names(args)) || any(!nzchar(names))))
    stop("Detected non-named arguments to NextMethod: ", deparse(sys.call()))
  .Internal(NextMethod(generic, object,...))

}

> foo <- function(...) UseMethod("foo")
> foo.A <- function(x, ...) str(list(x=x, ...))
> foo.B <- function(x, a=1, b=2, ...) NextMethod("foo", x, a=a, b)
> x <- structure(NA, class=c("B", "A"))
> foo(x)
Error in NextMethod("foo", x, a = a, b) :
  Detected non-named arguments to NextMethod: NextMethod("foo", x, a = a, b)

Note that this does not, as intended, test for non-named arguments in the call to the generic.

/Henrik
PS. I'm adding this to the trackers for the record. I don't expect anyone to go implement it, unless it's obvious how and where to add such protections.