在新版本的软件包中重命名函数时,是否有最佳/推荐的做法?

Mai*_*ura 37 r roxygen

我正在更新一个旧包并缩短了一堆很长的函数名.如何让用户知道旧函数已被弃用?我记录了所有内容roxygen2所以我想知道#' @alias我应该使用什么?思考?

Bri*_*ggs 48

即使您只是缩短功能名称,我仍然会像对包的公共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")
}
Run Code Online (Sandbox Code Playgroud)

首次发布新名称:

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")
}
Run Code Online (Sandbox Code Playgroud)

因此,它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"
Run Code Online (Sandbox Code Playgroud)

如果你进行了更改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")
Run Code Online (Sandbox Code Playgroud)

请注意,这是一个错误并停止; 它没有继续打电话alchemy.

在稍后的版本中,您可以完全删除此功能,但我会将其置于此状态作为路标.

你提到过使用roxygen.当您将第一个转换为不推荐使用时,可以将@rdname更改为package-deprecated,在描述的开头添加一行表示不推荐使用,将新函数添加到@seealso.当它更改为defunct时,将@rdname更改为package-defunct.

  • +1这是一个很好的答案,值得赏心悦目. (5认同)

rus*_*rce 22

我想"正确"的答案取决于你想要什么.从我的观点来看:

  1. 杰夫和布兰登的方法存在的问题是你的索引会列出两个函数名,并且没有说明哪个是首选名.此外,如果没有某种.Deprecated调用,用户更不可能知道调用该函数的首选方式是什么.
  2. Brian的方法存在的问题是,我不清楚将多个函数列为已弃用的过程.

所以,请在下面输入我的示例.在另一个位置,我定义了函数的"好"版本(例如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
Run Code Online (Sandbox Code Playgroud)


Del*_*eet 5

我遇到这个问题有一段时间了,无法找到好的解决方案。然后我发现了这个。尽管如此,对于简单的情况来说,上述答案过于复杂,人们只想:1)添加一个别名,以便旧代码不会停止工作,2)别名必须与内置文档一起使用,3)它应该用 roxygen2 来完成。

首先,添加函数的副本:

old_function_name = new_function_name
Run Code Online (Sandbox Code Playgroud)

然后,new_function_name()将定义的位置添加到 roxygen2 中:

#' @export new_function_name old_function_name
#' @aliases old_function_name
Run Code Online (Sandbox Code Playgroud)

现在旧函数可以工作,因为它只是新函数的副本,并且文档可以工作,因为您设置了别名。旧版本也会被导出,因为它包含在@export.