So this is an interesting gotcha in R (or at least I thought so). Suppose you have an object of class foo, where the “class” here is a class in the S3 sense. So you create a print method for the foo class, by writing a function print.foo. You create an object y, that has class foo. You pass that object to the print method. You’d like print to be able to say something like
Hello world, my name is y
Damned if I could write a print.foo function that would do that.
Here is one of my failed attempts:
> y <- 1:10
> class(y) <- "foo"
> print.foo <- function(x)
cat(paste("Hello world, my name is",
deparse(substitute(x))))
> y
Hello world, my name is structure(1:10, class = "foo")
You can see that I’ve tried to have object y print itself, so the generic print function has called print.foo to do that, but with the deparse(substitute(x)) trick not working the way it usually does.
On the other hand:
> myprint <- function(x)cat(paste("Hello world, my name is",
deparse(substitute(x))))
> myprint(y)
Hello world, my name is y
which is the desired behavior.
print is a generic function, which uses UseMethod for method dispatch:
> print
function (x, ...)
UseMethod("print")
So the object y gets handed down to print.foo from the generic print function via UseMethod. This is getting into parts of R that I don’t fully understand, but it looks like UseMethod is evaluating the object y before passing it down to print.foo. Hence substitute doesn’t work as it (usually?) does. Weird.
On the other hand, check out this:
> summary.foo <- function(object){
cl <- match.call()
z <- list(call=cl)
class(z) <- "summary.foo"
return(z)
}
> print.summary.foo <- function(x)
cat(paste("Hello world my name is",x$call$object,"\n"))
> summary(y)
Hello world my name is y
Update (after talking with Jan de Leeuw):
Jan points out that for the example above print(y) works as it should. The issue seems to be related to the way R’s command line parser works. The documentation (the R Language Definition) says its a “read-eval-print loop”. Which prompted Jan to say that “the question is really if an object evaluates to itself”.