2016-11-14 42 views
0

我提出一個短碼來創建S4類myclass,並確保如果他們驗證由一個參數給定的條件paramS4類構造函數和驗證

setClass("myclass", slot = c(x = "numeric")) 

#constructor 
ValidmyClass<- function(object, param = 1) 
{ 
if([email protected] == param) return(TRUE) 
else return("problem") 

} 
setValidity("myclass", ValidmyClass) 

setMethod("initialize","myclass", function(.Object,...){ 
.Object <- callNextMethod() 
validObject(.Object,...) 
.Object 
}) 

對於我得到以下錯誤消息對象被創建Error in substituteFunctionArgs(validity, "object", functionName = sprintf("validity method for class '%s'", : trying to change the argument list of for validity method for class 'myclass' with 2 arguments to have arguments (object)

我明白這個問題,但我找不到解決這個問題的方法。有關setValidity的文檔提到參數方法應該是「有效性方法;即NULL或一個參數(對象)的函數」。因此從我的理解中排除了不止一個論點。

不過,這個例子背後的想法是,我希望能夠根據外部給定參數的值測試myclass對象的構造。如果要添加更多條件,我希望有足夠的靈活性,因此只需要更新功能ValidmyClass,而無需添加更多插槽。

回答

1

有效性函數必須有一個名爲object的參數。當我需要創建一個參數函數,但實際上有更多參數或數據要傳入時,我經常會使用閉包。在這裏你的ValidmyClass的實現改變了,它現在將返回實際的有效性函數。外圍函數的參數是那麼一套額外的參數你有興趣

setClass("myclass", slot = c(x = "numeric")) 

#constructor 
ValidmyClass <- function(param) { 
    force(param) 
    function(object) { 
    if ([email protected] == param) TRUE 
    else "problem" 
    } 
} 

setValidity("myclass", ValidmyClass(1)) 

而且有效性函數初始化上自動調用。但是,在創建對象後更改插槽x時不可以。

setMethod("initialize", "myclass", function(.Object,...) { 
    .Object <- callNextMethod() 
    .Object 
}) 

new("myclass", x = 2) 
new("myclass", x = 1) 

有關關閉更多信息,請adv-R。雖然我認爲這回答你的問題,但我不明白這個實現如何實際上有幫助。當你定義你的類時,你基本上也修復了有效函數知道的其他參數。如果您有幾個可以抽象有效性函數的類,那麼我會使用閉包。如果你有一個類在運行時改變參數,我會考慮給這個類添加一個插槽。如果您不想更改類定義,則可以添加類列表的插槽,您可以在其中傳遞任意數量的值以進行測試。