R-alpha: UseMethod

Thomas Lumley (thomas@biostat.washington.edu)
Tue, 7 Jan 1997 11:10:49 -0800 (PST)


Date: Tue, 7 Jan 1997 11:10:49 -0800 (PST)
From: Thomas Lumley <thomas@biostat.washington.edu>
To: r-testers <r-testers@stat.math.ethz.ch>
Subject: R-alpha: UseMethod
In-Reply-To: <199701062150.KAA10367@stat13.stat.auckland.ac.nz>


UseMethod still isn't quite right.  If a function declares some formal 
parameters it can't then use UseMethod because those parameters will not 
be rematched correctly. The example is from the survival4 library:

survfit <- function (formula, data, weights, subset, na.action, ...) {
# various stuff
    if (!inherits(formula, 'formula')) temp <- UseMethod("survfit")
    else
# more stuff

There is no obvious way to convert this to R. (It looks like this could 
be rewritten to make survfit generic and then change this function to 
survfit.default but this doesn't work).

I have written a replacement which gives the S syntax for UseMethod and 
seems to work properly.  It does rely on the fact that methods for [ and 
[[ are handled internally rather than by generic functions. People 
converting S code may want to use this as an additional function. It 
isn't a drop-in replacement for the R UseMethod as the syntax is
SUseMethod("blah",x) (with x optional) 
rather than
UseMethod("blah",x,...)
so it always passes all the arguments of the calling function to the 
method. Also, it can only be called inside a function (in R you can, for 
example, type UseMethod("plot",rnorm(100),rnorm(100)) at the global 
prompt, though I can't see why you would want to).

Here it is:
"SUseMethod" <- function (generic, classobj = NULL) 
{ 
        call <- sys.call(sys.parent())
	if (is.null(classobj)) 
		classobj <- eval(call[[2]], sys.frame(sys.parent()))
	classlist <- class(classobj)
	classlist <- c(classlist, "default")
	while (!exists(paste(generic, classlist[[1]], sep = "."
	),mode="function",inherits=TRUE) && length(classlist) > 1) 
classlist <- classlist[-1]
        methodname<-paste(generic, classlist[[1]], sep = "."
	)
	if (!exists(methodname,mode="function",inherits=TRUE))
		stop("No method found")
	call[[1]] <- as.name(methodname)
	eval(call, sys.frame(-2))
}


Thomas Lumley
------------------------------------------------------+------
Biostatistics		: "Never attribute to malice what  :
Uni of Washington	:  can be adequately explained by  :
Box 357232		:  incompetence" - Hanlon's Razor  :
Seattle WA 98195-7232	:				   :
------------------------------------------------------------


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
r-testers mailing list -- For info or help, send "info" or "help",
To [un]subscribe, send "[un]subscribe"
(in the "body", not the subject !)  To: r-testers-request@stat.math.ethz.ch
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-