我正在更新一个旧软件包,并缩短了一些非常长的函数名称。如何让用户知道旧函数已被弃用? 我使用 roxygen2
记录所有内容,所以我想知道是否应该使用 #' @alias
? 你有什么想法吗?
即使只是缩短函数名称,我仍然建议将其视为公共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更改为package-deprecated,在描述的开头添加说明已经被弃用了,并将新函数添加到“@seealso”中。当它变成无效后,将@rdname更改为package-defunct。
我猜“正确”的答案取决于你想要什么。从我的角度来看:
接下来是我的示例。在另一个位置中,我定义了函数的“好”版本(例如alchemy、latinSquareDigram)。这里我定义了所有我想要生成弃用警告的旧“坏”版本。我采用了car包的方法,将所有使用弃用版本的函数调用改为使用...作为参数。这有助于避免一堆杂乱的@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
old_function_name = new_function_name
然后,在定义new_function_name()
的地方,添加到roxygen2中:
#' @export new_function_name old_function_name
#' @aliases old_function_name
现在旧函数仍然可用,因为它只是新函数的复制品,文档也可以工作,因为您设置了别名。旧版本也被导出,因为它包含在@export
中。
.Deprecated
的唯一原因(参见@GSEE)是如果您计划在未来发布中基本更改功能或停止支持某些功能。如果是这种情况,可以使用.Defunct
或.Deprecated
。
some_func <- new_func_name <- function(x)
并使用 @alias 指令。如果您想要它们都在命名空间中,您需要@export some_func new_fund_name
。请参阅 ?namespace_roclet。对我来说,这听起来不像是您正在更改函数,只是更改名称 - 因此,?Deprecated 看起来并不适用。 - Brandon Bertelsen