2012-04-11 24 views
31

我正在更新舊的軟件包並縮短了一大堆真正長的函數名稱。如何讓用戶知道舊功能已被棄用?我用roxygen2記錄了一切,所以我想知道#' @alias是我應該使用的嗎?思考?在新版本的包中重命名函數時,是否有最佳/推薦的做法?

+7

查看'?棄用的' – GSee 2012-04-11 02:47:32

+0

@alias只允許用戶通過?help找到函數的文檔。最好定義內聯和導出舊的和新的。 'some_func < - new_func_name < - function(x)'並使用@alias指令。如果你希望它們都在命名空間中,你需要'@export some_func new_fund_name'。請參閱?namespace_roclet。對我而言,聽起來並不像你在改變功能,只是改變了名字 - 所以?棄用似乎並不適用。 – 2012-04-11 05:09:43

+0

非常感謝@BrandonBertelsen 我建議你將它發佈爲答案,以便對其他人有用。 – Maiasaura 2012-04-12 16:28:25

回答

42

儘管您只是縮短了函數名稱,但我仍然會將它與對包的公共API進行的任何更改相提並論:在引入新函數時將舊函數棄用/取消階段。

在第一階段,針對每個功能要縮短(我們稱之爲transmute_my_carefully_crafted_data_structure_into_gold)這個名字,你跟上該簽名的功能,但將所有實際的代碼到你新命名的功能(姑且稱之爲alchemy )。

最初:

transmute_my_carefully_crafted_data_structure_into_gold <- function(lead, alpha=NULL, beta=3) { 
    # TODO: figure out how to create gold 
    # look like we are doing something 
    Sys.sleep(10) 
    return("gold") 
} 

首次發佈了新的名字:

transmute_my_carefully_crafted_data_structure_into_gold <- function(lead, alpha=NULL, beta=3) { 
    .Deprecated("alchemy") #include a package argument, too 
    alchemy(lead=lead, alpha=alpha, beta=beta) 
} 

alchemy <- function(lead, alpha=NULL, beta=3) { 
    # TODO: figure out how to create gold 
    # look like we are doing something 
    Sys.sleep(10) 
    return("gold") 
} 

這樣transmute_my_carefully_crafted_data_structure_into_gold開始圍繞alchemy瘦包裝,另外還有.Deprecated通話。

> transmute_my_carefully_crafted_data_structure_into_gold() 
[1] "gold" 
Warning message: 
'transmute_my_carefully_crafted_data_structure_into_gold' is deprecated. 
Use 'alchemy' instead. 
See help("Deprecated") 
> alchemy() 
[1] "gold" 

如果您更改alchemy,它仍然是由transmute_my_carefully_crafted_data_structure_into_gold進行,因爲這只是調用了前者。但是,即使alchemy確實不會更改transmute_my_carefully_crafted_data_structure_into_gold的簽名;在這種情況下,您需要儘可能將舊參數映射到新參數中。

在以後的版本中,您可以將.Deprecated更改爲.Defunct

> transmute_my_carefully_crafted_data_structure_into_gold() 
Error: 'transmute_my_carefully_crafted_data_structure_into_gold' is defunct. 
Use 'alchemy' instead. 
See help("Defunct") 

請注意,這是一個錯誤,並停止;它不會繼續並致電alchemy

您可以在稍後的版本中完全刪除此功能,但我會將其作爲路標保留在此狀態。

你提到使用roxygen。當您將第一次轉換爲不推薦使用時,可以將@rdname更改爲不使用數據包,在描述的開頭添加一行說明已過時,將新函數添加到@seealso。當它更改爲不可用時,將@rdname更改爲package-defunct。

+5

+1這是一個很好的答案,值得賞賜。 – Andrie 2012-04-13 19:09:16

+1

感謝您花時間寫出這個偉大的迴應。乾杯。 – Maiasaura 2012-04-19 17:24:27

3

在將過長的函數名稱轉換爲更短的版本時,我建議只將這兩個名稱導出爲相同的函數(請參閱@布蘭登的評論)。這將允許舊代碼繼續工作,同時爲新用戶提供更方便的選擇。

在我看來,標記.Deprecated(請參閱@GSEE)的唯一原因是,如果您打算從根本上更改功能或停止支持未來發行版中的某些功能。如果是這種情況,您可以使用.Defunct.Deprecated

20

我猜「正確」的答案取決於你想要什麼。在我看來:

  1. 傑夫和布蘭登的方法的問題是,您的索引將列出這兩個函數名稱,並沒有指出哪個是首選名稱。此外,如果沒有某種.deprecated調用,用戶更不可能知道調用函數的首選方式是什麼。
  2. Brian的方法存在的問題是,將不止一個函數列爲已棄用的過程對我而言並不清楚。

因此,請在下面輸入我的示例。在另一個位置,我定義了這些函數的'好'版本(例如鍊金術,拉丁方陣)。在這裏,我定義了所有我想爲其生成棄用警告的舊'糟糕'版本。我遵循汽車包的方法,並將已棄用版本的所有函數調用改爲使用...作爲參數。這幫助我避免了一堆混亂的@param語句。我也使用@name和@docType指令使「yourPackageName-deprecated」出現在索引中。也許有人有更好的方式來做到這一點?

現在,每個不推薦使用的函數仍然顯示在索引中,但在它們旁邊顯示「yourPackageName軟件包中的棄用函數」,並且對它們的任何調用都會生成棄用警告。要從索引中刪除它們,你可以刪除@aliases指令,但是你會得到用戶級的未公開的代碼對象,我認爲它是不好的形式。

#' Deprecated function(s) in the yourPackageName package 
#' 
#' These functions are provided for compatibility with older version of 
#' the yourPackageName package. They may eventually be completely 
#' removed. 
#' @rdname yourPackageName-deprecated 
#' @name yourPackageName-deprecated 
#' @param ... Parameters to be passed to the modern version of the function 
#' @docType package 
#' @export latinsquare.digram Conv3Dto2D Conv2Dto3D dist3D.l 
#' @aliases latinsquare.digram Conv3Dto2D Conv2Dto3D dist3D.l 
#' @section Details: 
#' \tabular{rl}{ 
#' \code{latinsquare.digram} \tab now a synonym for \code{\link{latinSquareDigram}}\cr 
#' \code{Conv3Dto2D} \tab now a synonym for \code{\link{conv3Dto2D}}\cr 
#' \code{Conv2Dto3D} \tab now a synonym for \code{\link{conv2Dto3D}}\cr 
#' \code{dist3D.l} \tab now a synonym for \code{\link{dist3D}}\cr 
#' } 
#' 
latinsquare.digram <- function(...) { 
    .Deprecated("latinSquareDigram",package="yourPackageName") 
    latinSquareDigram(...) 
} 
Conv3Dto2D <- function(...) { 
    .Deprecated("conv3Dto2D",package="yourPackageName") 
    conv3Dto2D(...) 
} 
Conv2Dto3D <- function(...) { 
    .Deprecated("conv2Dto3D",package="yourPackageName") 
    conv2Dto3D(...) 
} 
dist3D.l <- function(...) { 
    .Deprecated("dist3D",package="yourPackageName") 
    dist3D(...) 
} 
NULL 
+2

爲什麼這沒有upvotes?!愛它! – 2013-02-28 01:26:39

+1

@ mathematical.coffee:謝謝!可能是因爲我在獎勵獲勝者8個月後提供了我的答案。 :)我嘗試了上述建議,並且對結果不滿意。所以,當我終於得到一個結果時,我很高興我發佈了我的答案。 – russellpierce 2013-02-28 06:27:12

+1

我發現賞金獲勝者很有幫助,但這肯定會增加它。我需要額外的roxygen2愛。 – 2013-12-20 00:45:30

2

我有這個問題一段時間,無法找到一個很好的解決方案。然後我發現了這一點。儘管如此,上面的答案對於一個簡單的情況來說過於複雜:1)添加一個別名,以便舊代碼不會停止工作; 2)別名必須與內置文檔配合使用; 3)它應該用roxygen2完成。

首先,添加函數的副本:

old_function_name = new_function_name 

然後,在new_function_name()的定義,添加到roxygen2:

#' @export new_function_name old_function_name 
#' @aliases old_function_name 

現在老功能的作品,因爲它僅僅是新函數的一個副本,並且由於您設置了別名,文檔可以工作。舊版本也被導出,因爲它包含在@export中。

相關問題