Search code examples
rr-s3

Where shall one put the ellipsis in S3 function overloads?


We have an S3 class for which we define plot and other generic functions. We are not sure where the ... has to go. There are two options:

  1. plot.hadronacf(x, col = "black", ...)
  2. plot.hadronacf(x, ..., col = "black")

Similarly also for print. and summary..

In the usage of summary it seems to be inconsistent:

summary(object, ...)

## Default S3 method:
summary(object, ..., digits)
## S3 method for class 'data.frame'
summary(object, maxsum = 7,
       digits = max(3, getOption("digits")-3), ...)

## S3 method for class 'factor'
summary(object, maxsum = 100, ...)

## S3 method for class 'matrix'
summary(object, ...)

## S3 method for class 'summaryDefault'
format(x, digits = max(3L, getOption("digits") - 3L), ...)
 ## S3 method for class 'summaryDefault'
print(x, digits = max(3L, getOption("digits") - 3L), ...)

For print it seems that the ellipsis goes to the end:

print(x, ...)

## S3 method for class 'factor'
print(x, quote = FALSE, max.levels = NULL,
      width = getOption("width"), ...)

## S3 method for class 'table'
print(x, digits = getOption("digits"), quote = FALSE,
      na.print = "", zero.print = "0",
      right = is.numeric(x) || is.complex(x),
      justify = "none", ...)

## S3 method for class 'function'
print(x, useSource = TRUE, ...)

It seems that ellipsis at the end is used in the majority. Is there some guideline for this?


Solution

  • There's no "right" way to do this. It's a matter of preference or a design decision based on what you think the function should do with "extra parameters". For example with the two variations A and B

    summary(object, maxsum = 100, ...)  # A
    summary(object, ..., maxsum = 100)  # B
    

    The only way you can pass a maxsum to version B is by a named parameter in the function call. Whereas, version A would take the second unnamed parameter and pass it to maxsum. They differ in how "important" that parameter is to the function call.