使用S4类进行错误处理

时间:2011-03-23 21:36:15

标签: r s4

我是新手。我正在尝试使用S4课程。在我的一些设置方法中,我想获取一个输入值并测试它是否有效。如果它有效,我想分配它。如果它无效,我想生成一个可以测试的警告。这是一个简单的例子:

 setClass("foo", representation(ind = "numeric"))

 setGeneric(name="setInd<-",def=function(object,value){standardGeneric("setInd<-")})

 setReplaceMethod(f="setInd",signature="foo",
 def=function(object,value){
   if(is.numeric(value)){
     object@ind<-value;}
   else{
     warning("Foobar")
   }
    return(object)}
 )

当我尝试分配字符时,会生成警告消息:

> thisFoo<-new("foo", ind = 2)
> thisFoo
An object of class "foo"
Slot "ind":
[1] 2


> setInd(thisFoo)<-"A"
Warning message:
In `setInd<-`(`*tmp*`, value = "A") : Foobar
> thisFoo
An object of class "foo"
Slot "ind":
[1] 2

但我希望能够测试分配失败。这样做的好方法是什么?感谢。

1 个答案:

答案 0 :(得分:2)

如果分配失败,我会返回错误而不是警告。警告会告诉您该过程已完成,但可能会产生意外结果。在您的情况下,该过程中止:

setReplaceMethod(f="setInd",signature="foo",
 def=function(object,value){
   if(!is.numeric(value))
     stop("Foobar")

   object@ind <- value  
   return(object)}
 )

使用stop可以使用tryCatch()try()构造。有关更多信息,请参阅相关帮助页面。例如:

tryCatch(setInd(thisFoo)<-"A",error=function(e){print("Hello")})

> X <- try(setInd(thisFoo) <- "A")
Error in `setInd<-`(`*tmp*`, value = "A") : Foobar
> if(is(X,"try-error")) setInd(thisFoo) <- 5
> thisFoo
An object of class "foo"
Slot "ind":
[1] 5

如果您确实需要处理警告,请查看withCallingHandlers。使用原始代码:

> withCallingHandlers({setInd(thisFoo)<-"A"},
+     warning = function(w) {print("Hello")})
[1] "Hello"
Warning message:
In `setInd<-`(`*tmp*`, value = "A") : Foobar

请注意,这比使用错误的上述选项更不直接。