The way UseMethod works in R

Viewed 1431
h <- function(x) {
  x <- 10
  UseMethod("h")
}
h.character <- function(x){ paste("char", x)}
h.numeric <- function(x) { paste("num", x)}
h("a")

The above code will output:

[1] "char a"

My deductive reasoning, from the below, says that the output should be "char 10".

According to the documentation of the UseMethod:

  1. Find the context for the calling function (the generic): this gives us the unevaluated arguments for the original call.

  2. Evaluate the object (usually an argument) to be used for dispatch, and find a method (possibly the default method) or throw an error.

  3. Create an environment for evaluating the method and insert special variables (see below) into that environment. Also copy any variables in the environment of the generic that are not formal (or actual) arguments.

  4. Fix up the argument list to be the arguments of the call matched to the formals of the method.

If I understand it right, in step 2, x would be evaluated to 'a'. But then in step 3, another variable x with the value of 10 is inserted into the environment to execute the method.

Wouldn't that override x to be 10 now? And finally in step 4, arguments are matched to the arguments of the method. So x, which is 10, is now the argument of the method.

What did I get wrong about

1 Answers

From ?UseMethod

Method dispatch takes place based on the class(es) of the first argument to the generic function or of the object supplied as an argument to ‘UseMethod’ or ‘NextMethod’.

So in this case

h <- function(x) {
  x <- 10
  UseMethod("h")
}

h("a")
#[1] "char a"

which function to call depends on the class of "a" when you call h using h("a") (class(es) of the first argument to the generic function).

But if you have

h <- function(x) {
  x <- 10
  UseMethod("h", x)
}

h("a")
#[1] "num a"

and when you call h("a") it will call h.numeric since it is the class UseMethod is given (class(es) ... of the object supplied as an argument to ‘UseMethod’).


So, the following would give "char 10" as the output when you call the generic function.

zz <- function(x) {

   UseMethod("zz", "w")
}
zz.character <- function(x){ paste("char", x)}
zz.numeric <- function(x) { paste("num", x)}

zz(10)
#[1] "char 10"
Related