[R] Best/safest way to use UseMethod()?

Henrik Bengtsson hb at maths.lth.se
Fri Nov 16 18:41:16 CET 2001

I raised the questions below a couple of months ago by sending it to the developers mailing list, but I don't know if it got through since no one replied to it.
Looking at the [R] distribution, the UseMethod() is used in the following way:
  alias <- function(object, ...) UseMethod("alias")
  barplot <- function(height, ...) UseMethod("barplot")
What I would like to point out here is that there is a first argument ('object' and 'height'). This might give a conflict if some one do like this    

  foo.Bar <- function(this, x=0, xidx=0) {
  	cat("In foo.Bar(): ", this, ", x=", x, ", xidx=", xidx, ".\n", sep="");
  foo.default <- function(...) {
  	str("Error: No default function found!");
  foo <- function(x, ...) UseMethod("foo");
  obj <- "Hello world!";
  class(obj) <- "Bar";
  foo(obj, xidx=1);
  foo(obj, x=1);             # <- PROBLEM HERE!
  foo(obj, x=1, xidx=1);     # <- PROBLEM HERE!
  foo(obj, xidx=1, x=1);     # <- PROBLEM HERE!
  foo.Bar(obj, x=1);
  foo.Bar(obj, x=1, xidx=1);

you will get that all the calls with an 'x=1' will call the default function. I just reported this as a bug, but as Peter Dalgaard kindly replied, the problem is that I used the argument 'x' in the defintion of the generic foo() function. Obvious, but I never saw since I kept all the foo() functions in different files. 

So to my question, is it correct to write a generic function without a first argument, e.g.

  foo <- function(...) UseMethod("foo");

It is obvious you would like to have '...'. It works for me, but can I expect it to work in the future? Also, is there are reason for not doing like this in the [R] core distribution? I think it would be safer and remove some strange behaviour for programmers "down the stream".

A related question here is, is there a reason why not all methods are defined generic with a '.default' definition too? For instance, now 'cat' is defined as

  cat <- function(..., file="", sep=" ", fill=FALSE, labels=NULL, append=FALSE) { ... }

If I create a class MyClass with a function cat (very probable), I would have to create a generic cat() function. Now I would like to distribute my class in a library/package and I do not have control of what libraries the user will load. Then I would need to do

  if (!exists("cat.default")) {
    if (exists("cat")) 
      cat.default <- cat
      cat <- function(x, ...) stop("No default method defined!");
  cat <- function(x, ...) UseMethod("cat");

to make sure that 1) there is a generic cat() function and that possible previously defined cat() functions are still available. I think this is "almost" a safe strategy, but I am not sure.


Henrik Bengtsson

Dept. of Mathematical Statistics @ Centre for Mathematical Sciences 
Lund Institute of Technology/Lund University, Sweden (+2h UTC)
Office: P316, +46 46 222 9611 (phone), +46 46 222 4623 (fax)
hb at maths.lth.se, http://www.maths.lth.se/matstat/staff/hb/

r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch

More information about the R-help mailing list