2011-11-10 86 views
0

無論是在包中還是偶爾在基本R中,我有時都想爲現有函數添加一點風味。大多數情況下,這是函數開始或結束時發生的細微變化(愚蠢的例子:我希望cat函數在默認情況下在最後包含換行符)。覆蓋方法使用原始實現來擴展它

現在我知道我可以簡單地通過將我的新實現分配給它的名稱來覆蓋現有的方法,但是:那麼,我仍然可以使用舊的方法嗎?在cat的情況下,我會做這樣的事情:

cat<-function(... , file = "", sep = " ", fill = FALSE, labels = NULL, 
    append = FALSE) 
{ 
    cat(..., "\n" , file = file, sep = sep, fill = fill, labels = labels, 
    append = append) 
} 

這意味着使用「舊」 cat在新的實施。現在,如果我理解R中的調用和後期綁定的任何操作,這將會失敗(無限遞歸)。

那麼,有沒有實現這一點(在功能的面向對象覆蓋的精神)的一種方式,而不是訴諸

  • 給我的新功能的另一個名字(我希望它「只是工作」)
  • 下其他名稱(然後,當我創建 這個功能在另一個R對話,我會忘記額外的步驟)
  • 使用原函數的所有源(如@Andrie說保存舊功能:重要的是要有最優雅的解決方案)

有沒有這方面的範例?或者我怎麼能以最安全的方式解決這個問題?或者我只是想太多?

編輯鑑於@ Andrie的回答:這可以做得很簡單。然而,如果我想改變程序包中另一個函數調用的程序包中的某些函數的行爲,Andrie的技巧將不起作用。

舉個例子:我已經對glmnet包的繪圖功能進行了大量的補充。但是如果你看看plot.cv.glmnet之類的東西,你會看到他們將該調用轉發給該包中的另一個函數,所以我真的需要將新版本注入到包中(順便說一句,可以用reassignInPackage)。但是當然,命名空間前綴將會失敗,因爲我剛剛替換了命名空間版本。這個例子並不像看起來那麼人爲:我去過那裏好幾次了。另一方面,也許有人會/可以爭辯說,我應該放棄我的要求,在這種情況下?這將是最好的方式去呢?

回答

7

如果我理解正確,我認爲這是一個簡單的問題,指的是namespace::function,即在這種情況下,在您的函數中使用base::cat

例如:

cat <- function(... , file = "", sep = " ", fill = FALSE, labels = NULL, 
    append = FALSE) 
{ 
    base::cat(..., "\n" , file = file, sep = sep, fill = fill, labels = labels, 
     append = append) 
} 

> cat("Hello", "world!") 
Hello world! 
> cat("Text on line 2") 
Text on line 2 
+0

<拍打前額/>。對於顯而易見的(像往常一樣,從我的角度來看)的觀察(通常來自你的部分)。無論哪種方式,我都會提高一點(請參閱我的編輯幾分鐘)。 –