2011-03-23 51 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