我正在更新旧包并缩短一堆非常长的函数名称。如何让用户知道旧函数已被弃用?我用roxygen2
记录了所有内容,所以我想知道#' @alias
是否应该使用?想法?
答案 0 :(得分:47)
即使您只是缩短功能名称,我仍然会像对包的公共API的任何更改一样对待它:随着新功能的引入,旧功能的弃用/废弃阶段。< / p>
在第一阶段,对于你想要缩短名称(让我们称之为transmute_my_carefully_crafted_data_structure_into_gold
)的每个函数,你保留一个带有该签名的函数,但是将所有实际代码移动到你新命名的函数中(let's称之为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
承载,因为它只调用前者。但是,即使transmute_my_carefully_crafted_data_structure_into_gold
发生,您也不会更改alchemy
的签名;在这种情况下,您需要将旧参数尽可能映射到新参数中。
在以后的版本中,您可以将.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更改为package-deprecated,在描述的开头添加一行表示不推荐使用,将新函数添加到@seealso。当它变为已失效时,请将@rdname更改为package-defunct。
答案 1 :(得分:22)
我猜“正确”的答案取决于你想要什么。从我的观点来看:
所以,请在下面输入我的示例。在另一个位置,我定义了函数的“好”版本(例如alchemy,latinSquareDigram)。在这里,我定义了我想要为其生成弃用警告的所有旧“坏”版本。我按照汽车包的方法,改变了我所有的函数调用,使用不推荐的版本作为参数。这有助于我避免一堆混乱的@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 :(得分:3)
在将过长的函数名称转换为较短版本的情况下,我建议只将两个名称导出为相同的函数(请参阅@Brandon的注释)。这将允许旧代码继续工作,同时为新用户提供更方便的替代方案。
在我看来,将标记为.Deprecated
(参见@GSEE)的唯一原因是,如果您计划从根本上更改功能或停止在将来的版本中支持某些功能。如果是这种情况,您可以使用.Defunct
或.Deprecated
。
答案 3 :(得分:3)
我有这个问题已经有一段时间了,无法找到一个好的解决方案。然后我发现了这个。但是,对于简单的情况,上面的答案过于复杂,人们只想: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中。