2011-03-23 79 views
3

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

> 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 

但是我想能够测试该分配失败:

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)){ 
    [email protected]<-value;} 
    else{ 
    warning("Foobar") 
    } 
    return(object)} 
) 

当我尝试指定的字符,该生成一条警告消息。这样做的好方法是什么?谢谢。

+1

在这种情况下,分配违反了类定义并且无论如何都会产生错误;测试是没有必要的。或者,使用'c(“foo”,“numeric”)作为替换方法的签名,并且再次尝试赋值会产生一个错误(因为没有方法匹配'c(“foo”,“character”) ')。正如约里斯提到的那样,用tryCatch抓住错误。 – 2011-03-24 02:41:27

回答

2

如果分配失败,我会返回一个错误,而不是一个警告。警告会告诉您该过程已经完成,但可能会产生意想不到的结果。在你的情况下,过程被中止:使用stop

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

    [email protected] <- value 
    return(object)} 
) 

允许您使用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 

请注意,这比使用错误的上述选项要简单得多。

+0

谢谢。这很好。 – jmmcnew 2011-03-24 14:52:09