BrodieG
BrodieG

Reputation: 52647

S4 Classes May Not Contain "try-error" Class Objects?

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

Answers (1)

Robert Krzyzanowski
Robert Krzyzanowski

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

Related Questions