Reputation: 52647
Reproducible example:
setClass("test", representation(a="ANY"))
A <- structure("blahblahblah", class="try-error")
new("test", a=A)
# Error in validObject(.Object) : invalid class “test” object: blahblahblah
I think the problem stems from line 29 of validObject
:
sloti <- try(switch(namei, .S3Class = S3Class(object),
slot(object, namei)), silent = TRUE)
which clearly will trick whatever follows when slot(object, namei)
returns a try-error
class object as is the case here.
Anyhow, just wanted to ask here if this seems like a bug to anyone else before I go off and propose a tryCatch
alternate.
And if you're curious as to why on earth I would be doing something like this, I am building S4 classes to store results of arbitrary expression evaluations, which in one of my test cases happened to contain the result of a try()
statement.
Upvotes: 2
Views: 205
Reputation: 9344
No, the issue is on the next line:
if (inherits(sloti, "try-error")) {
errors <- c(errors, sloti)
next
}
A hacky workaround would be:
safeNew <- function(...) {
suppressMessages(trace(validObject, quote(inherits <- function(...)
if (eval.parent(substitute(namei != '.S3Class' && class(slot(object, namei)) == 'try-error'))) FALSE
else base::inherits(...)), at = 11))
capture.output(res <- new(...))
suppressMessages(untrace(validObject))
res
}
setClass("test", representation(a="ANY"))
A <- structure("blahblahblah", class="try-error")
safeNew("test", a = A) # Now returns no error.
EDIT: I changed some code above so it now type checks correctly rather than disable type checking. For example,
setClass("test", representation(a="ANY", b = "character"))
A <- structure("blahblahblah", class="try-error")
safeNew("test", a = A, b = 5)
# Error in validObject(.Object) :
# invalid class “test” object: invalid object for slot "b" in class "test": got class "numeric", should be or extend class "character"
Upvotes: 1