scott.chasalow@bms.com
2005-Mar-18 18:21 UTC
[Rd] 2 possible bugs in function validObject (PR#7735)
Hi,> R.version.string[1] "R version 2.0.1, 2004-11-15" I have found two possible bugs in function validObject. Details below. Cheers, Scott =================================Scott D. Chasalow Principal Statistician Statistical Genetics and Biomarkers Bristol-Myers Squibb Company Email: scott.chasalow <AT> bms.com ================================= ------ BEGIN R commands and output ------ setClass("track", representation(x = "numeric", y = "numeric")) validTrackObject <- function(x){ if(length(x@x) == length(x@y)) TRUE else paste("Oooo that's bad", LETTERS[1:4]) } ## assign the function as the validity method for the class setValidity("track", validTrackObject) ## Now define class "field", to include a "track" slot: setClass("field", representation(t = "track", z = "character")) setValidity("field", function(object) if (length(object@z) > 0) TRUE else "z is way short.") ## A good track: OK t1 <- new("track", x = 1:10, y = sort(rnorm(10))) ## A good field: OK f1 <- new("field", t = t1, z = letters[1:10]) ## A bad field: OK f1 <- new("field", t = t1) Error in validObject(.Object) : Invalid "field" object: z is way short. ## Make t1 a bad track: minor problem with error msg formatting? t1@x <- 1:20 validObject(t1) Error in validObject(t1) : Invalid "track" object: 1: Oooo that's bad A Invalid "track" object: 2: Oooo that's bad B Invalid "track" object: 3: Oooo that's bad C Invalid "track" object: 4: Oooo that's bad D ## A bad field, because it contains a bad track (an invalid track ## object): fools validObject. I expected that I would fail to create ## f1 here, or at least that validObject(f1) would report the problem ## with t1 in slot t. f1 <- new("field", t = t1, z = letters[1:10]) validObject(f1) [1] TRUE validObject(f1@t) Error in validObject(f1@t) : Invalid "track" object: 1: Oooo that's bad A Invalid "track" object: 2: Oooo that's bad B Invalid "track" object: 3: Oooo that's bad C Invalid "track" object: 4: Oooo that's bad D ## A bad field, because I try to put a non-track in the track slot: OK f1 <- new("field", t = 1:3, z = letters[1:10]) Error in validObject(.Object) : Invalid "field" object: Invalid object for slot "t" in class "field": got class "integer", should be or extend class "track" ------ END R commands and output ------ So, we see that validity of slot t is not tested, in the sense of calling validObject on the slot. The documentation for validObject suggests (to me at least) that validObject should be called on the slot. Instead, validObject seems to test only that the slot has the right class. I'm not sure precisely what the author intended validObject to do, but this seems to me either a bug in the code, or else somewhat misleading documentation. Concerning the error msg formatting, I suspect it possibly is not as the author intended? The code in validObject to create this error msg is: stop(paste("Invalid \"", Class, "\" object: ", paste(paste(1:length(errors), errors, sep = ": ")), sep = "", collapse = "\n")) As far as I can see, the second call to paste does nothing here. Perhaps this is what was intended?: stop(paste("Invalid \"", Class, "\" object: ", paste(paste(1:length(errors), errors, sep = ": "), collapse = "\n"), sep = "")) This would give: Error in validObj(t1) : Invalid "track" object: 1: Oooo that's bad A 2: Oooo that's bad B 3: Oooo that's bad C 4: Oooo that's bad D Personally, I like this even better: stop(paste("Invalid \"", Class, "\" object:\n", paste(paste(1:length(errors), errors, sep = ": "), collapse = "\n"), sep = "")) Error in validObj(t1) : Invalid "track" object: 1: Oooo that's bad A 2: Oooo that's bad B 3: Oooo that's bad C 4: Oooo that's bad D