Sklyar, Oleg (MI London)
2008-May-13 10:54 UTC
[Rd] 'cat' and 'write' as generic, just like 'c', 'cbind' etc?
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}}