## String class using S4 methods setClass("String",representation(string = "character")) ## Simple interface to make a new instance string = function(x) { new("String",string=as.character(x)) } ### length,summary and show are all different ### * length is a "primitive" ### * summary is a S3 method ### * show is a S4 standardGeneric ### They all get treated the same here. No need to define them as as ### generic as done below. These need to have their arguments match ### (or possibly extend) those of the generic function. See ?setMethod ### for the gory details. ## length setMethod("length","String",function(x) nchar(x@string)) setMethod("summary","String", function(object,...) { return(table(strsplit(object@string,""))) }) ## print method setMethod("show","String", function(object) { cat(object@string,"\n") }) ### Slice is not defined. It is made a generic object first, with the ### default definition setting up the formal arguments and default ### values. This is also done with the other remaining function ### definitions. setGeneric("slice", function(object,index) standardGeneric("slice")) setMethod("slice","String", function(object,index) { tmp = paste(unlist(strsplit(object@string,""))[index], sep="",collapse="") return(string(tmp)) }) setGeneric("concat", function(e1,e2) standardGeneric("concat")) setMethod("concat","String", function(e1,e2) { tmp = paste(e1@string,e2,sep="",collapse="") return(string(tmp)) }) setGeneric("rept", function(e1,e2) standardGeneric("rept")) setMethod("rept","String", function(e1,e2) { tmp = paste(rep(e1@string,e2),sep="",collapse="") return(string(tmp)) }) ### return vector of character type. Can't return vector of "String" ### type only a list setMethod("split","String", function(x,f) { tmp = unlist(strsplit(x@string,f)) return(tmp) }) setGeneric("upcase", function(object) standardGeneric("upcase")) setMethod("upcase","String",function(object) { string(toupper(object@string)) }) setGeneric("downcase", function(object) standardGeneric("downcase")) setMethod("downcase","String",function(object) { string(tolower(object@string)) }) ### These are syntactical shortcuts to some of the functions above The ### setMethod works for them. They need to have their arguments match ### those of the generic functions. This is why "[" has such a funny ### looking argument list, as the generic function "[" is used for ### vectors, matrices and arrays. setMethod("[","String",function(x,i,j,...,drop) slice(x,i)) setMethod("+","String",function(e1,e2) concat(e1,e2)) setMethod("*","String",function(e1,e2) rept(e1,e2)) setMethod("/","String",function(e1,e2) split(e1,e2)) ### A Sentence class extending String setClass("Sentence",contains=c("String")) ## a new instance sentence = function(x) { new("Sentence",string=x) } ## a sentence method setGeneric("punctuate", function(object) standardGeneric("punctuate")) setMethod("punctuate","Sentence",function(object) { ## add a period, and capitalize the first letter chars = split(object,"") chars[1] = toupper(chars[1]) if(chars[length(chars)] != ".") chars[length(chars)+1] = "." return(sentence(paste(chars,sep="",collapse=""))) })