[Rd] 'cat' and 'write' as generic, just like 'c', 'cbind' etc?

Sklyar, Oleg (MI London) osklyar at maninvestments.com
Tue May 13 12:54:10 CEST 2008


Dear list:

is there any good reason why 'c', 'cbind', 'rbind' etc (all defined as
'function(..., <rest>)') are generic and thus methods can be defined
whereas such quite useful functions like 'cat' and 'write' are not? 

Would it not be reasonable to add such functionality? This would allow
to define S3/S4 methods for cat and write for complex objects defining
the way they should be output to files and std out.

As a use case, I am working with ASCII files formatted in a particular
way, when they are read, corresponding objects are created that
replicate their structure and thus it seems reasonable to recreate the
same ASCII structure when one does cat or write (which calls cat) on
those objects. The default print/show would actually in this case have
different, more compact output.

I might be doing something wrong about defining 'cat' as a method, but
its help page indeed does not mention anything about being generic,
whereas those of 'c', 'cbind' etc do. So the question is rather: could
it be made generic?

Thanks for responces,
Oleg

The following example shows the way 'c' can be redefined, while 'cat'
cannot although they are redefined following exactly the same
methodology:

## R 2.7.0 (2008-04-22) Linux 2.6.9-42, x86_64

setClass("MyClass", representation("numeric", comment="character"))

setGeneric("c")
setMethod("c", "MyClass",
    function(x, ..., recursive=FALSE) {
        print("CALLED: c S4 method")
        args = list(x,...)
        if (!all(sapply(args, inherits, "MyClass")))
            stop("all arguments must be of class MyClass")
        data = lapply(args, function(x) x at .Data)
        comm = lapply(args, function(x) x at comment)
        new("MyClass", do.call("c", data), comment=do.call("c", comm))
    }
)

a = new("MyClass", runif(3), comment=c("a","b","c"))
b = new("MyClass", -runif(3), comment=c("d","e","f"))
c(a,b)

## does not work in S4
setGeneric("cat")
setMethod("cat", "MyClass",
    function(x, ..., file = "", sep = " ", fill = FALSE, labels = NULL,
        append = FALSE) {
        print("CALLED: cat S4 method")
        cat("Data:", x at .Data,"\n", file=file, append=append)
        cat("Comment:", x at comment, "\n", file=file, append=append)
        invisible(NULL)
    }
)
## omitting x following the function definition does not solve the
problem

cat(a,"\n")
cat(b,"\n")

## does not work in S3
cat.MyClass = function(..., file = "", sep = " ", fill = FALSE, labels =
NULL,
    append = FALSE) {
    print("CALLED: cat.MyClass")
    x = c(...)
    cat("Data:", x at .Data,"\n", file=file, append=append)
    cat("Comment:", x at comment, "\n", file=file, append=append)
    invisible(NULL)
}

cat(a,"\n")



Dr Oleg Sklyar
Technology Group
Man Investments Ltd
+44 (0)20 7144 3803
osklyar at maninvestments.com


**********************************************************************
The contents of this email are for the named addressee(s...{{dropped:22}}



More information about the R-devel mailing list