2016-04-01 52 views
2

我正在尋找一種方法來驗證我的包中的S3對象Momocs我們可以將S3靈活性與S4表示檢查結合起來嗎?

該軟件包的早期版本是使用S4編寫的,爲了靈活性,我將其移回S3,因爲用戶更喜歡S3,因爲我並不需要多重繼承,etc.。這種變化的主要成本實際上是損失了S4表示/有效性檢查。

我的問題如下:我們如何防止一個無意中「無效」的S3對象,例如試圖擴展現有的方法或操縱對象結構?

我已經寫了一些validate函數,但到目前爲止,我只在關鍵步驟之前驗證,通常是將對象從一個類轉換爲另一個類。

我的問題是:

  • 我想有我魚與熊掌兼得(S3靈活性和S4表示檢查)?在這種情況下,我需要在包裝的所有方法中添加我的validate函數?
  • 還是在S3之上有一個更聰明的方法,就像「我們每次在某個特定類的對象上做某件事時,都會調用一個validate函數」?

回答

2

最簡單的事情是編寫每個類的驗證函數,並在S3方法派發之前或在每個類的方法內傳遞對象。以下是帶有"example_class"類的對象稱爲check_example_class一個簡單的驗證功能的例子:

check_example_class <- function(x) { 
    stopifnot(length(x) == 2) 
    stopifnot("a" %in% names(x)) 
    stopifnot("b" %in% names(x)) 
    stopifnot(is.numeric(x$a)) 
    stopifnot(is.character(x$b)) 
    NULL 
} 
print.example_class <- function(x, ...) { 
    check_example_class(x) 
    cat("Example class object where b =", x$b, "\n") 
    invisible(x) 
} 

# an object of the class 
good <- structure(list(a = 1, b = "foo"), class = "example_class") 

# an object that pretends to be of the class 
bad <- structure(1, class = "example_class") 

print(good) # works 
## Example class object where b = foo 
print(bad) # fails 
## Error: length(x) == 2 is not TRUE 
+0

我已經有這樣的[事情](https://github.com/vbonhomme/Momocs/blob/master/R/ cl-validate.R),但我想知道是否可以避免將它添加到任何地方。將它印在'print'中是非常好的技巧! –

+1

@VincentBonhomme這是S3與S4的權衡。您必須手動驗證,因爲S3實際上只是派遣類屬性;它不提供任何其他基礎設施來進行任何驗證。 – Thomas

相關問題