sdgfsdh
sdgfsdh

Reputation: 37065

S4 classes - overload a method with a variable number of arguments

I would like to have a variable number of arguments in my S4 generic myMethod such that these are both valid:

myMethod(100)
myMethod(100, 200)

Here is my attempt at a definition:

setGeneric(
    "myMethod", 
    function(x) {

        standardGeneric("myMethod")
    })

setMethod(
    "myMethod", 
    signature = c("numeric"), 
    definition = function(x) {

        print("MyMethod on numeric")
    })

setMethod(
    "myMethod", 
    signature = c("numeric", "numeric"), 
    definition = function(x, y) {

        print("MyMethod on numeric, numeric")
    })

However, this gives the error:

Error in matchSignature(signature, fdef) : more elements in the method signature (2) than in the generic signature (1) for function ‘myMethod’

Upvotes: 1

Views: 1524

Answers (2)

Martin Morgan
Martin Morgan

Reputation: 46866

It's worth clarifying whether you want to dispatch (select a method) on more than one argument (in which case include all argument names in the signature= of setGeneric())

setGeneric("fun", function(x, y) standardGeneric("fun"),
           signature=c("x", "y"))

setMethod("fun", c(x="numeric", y="numeric"), function(x, y) {
    "fun,numeric,numeric-method"
})

versus dispatching based on the first (include only the first argument in signature=) and either require all methods to have additional arguments (name the arguments in the generic function)

setGeneric("fun", function(x, y) standardGeneric("fun"),
           signature="x")

setMethod("fun", c(x="numeric"), function(x, y) {
    "fun,numeric-method"
})

or only some methods (use ... in the generic, and name the arguments in the method).

setGeneric("fun", function(x, ...) standardGeneric("fun"),
           signature="x")

setMethod("fun", c(x="numeric"), function(x, y) {
    "fun,numeric-method"
})

Upvotes: 3

shadow
shadow

Reputation: 22313

Your generic should support 2 arguments.

setGeneric(
  "myMethod", 
  function(x, y) {
    standardGeneric("myMethod")
  })

Also the function in your second method should actually support two arguments:

setMethod(
  "myMethod", 
  signature = c("numeric", "numeric"), 
  definition = function(x, y) {
    print("MyMethod on numeric, numeric")
  })

More generally, if you want to specify arbitrarily many arguments, you should have a look at the elipsis argument ....

Upvotes: 1

Related Questions