Tôi đang cập nhật một gói cũ và rút ngắn một loạt các tên hàm thực sự dài. Làm cách nào để cho người dùng biết chức năng cũ đã không được chấp nhận? Tôi ghi lại mọi thứ với roxygen2
vì vậy tôi tự hỏi nếu #' @alias
là những gì tôi nên sử dụng? Suy nghĩ?Có thực tiễn tốt nhất/được đề nghị để làm theo khi đổi tên các chức năng trong một phiên bản mới của gói không?
Trả lời
Mặc dù bạn chỉ cần rút ngắn tên hàm, tôi vẫn xử lý nó với cùng một hiệu ứng như bất kỳ thay đổi nào đối với API công khai của gói: với các giai đoạn không dùng nữa/không còn tồn tại đối với các chức năng cũ. Trong giai đoạn đầu tiên, đối với mỗi chức năng bạn muốn rút ngắn tên (hãy gọi nó là transmute_my_carefully_crafted_data_structure_into_gold
), bạn giữ một hàm với chữ ký đó, nhưng di chuyển tất cả mã thực tế vào hàm mới được đặt tên của bạn (hãy gọi nó là alchemy
)).
Ban đầu:
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")
}
đầu tiên phát hành với tên mới:
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")
}
Vì vậy mà transmute_my_carefully_crafted_data_structure_into_gold
bắt đầu như là một wrapper mỏng xung quanh alchemy
, với thêm .Deprecated
gọi.
> 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"
Nếu bạn thay đổi alchemy
, nó vẫn mang theo transmute_my_carefully_crafted_data_structure_into_gold
vì đó chỉ gọi cũ. Tuy nhiên, bạn không thay đổi chữ ký của transmute_my_carefully_crafted_data_structure_into_gold
ngay cả khi alchemy
có; trong trường hợp đó, bạn cần ánh xạ, cũng như có thể, các đối số cũ vào các đối số mới.
Trong bản phát hành sau, bạn có thể thay đổi .Deprecated
thành .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")
Lưu ý rằng đây là lỗi và dừng; nó không đi trước và gọi alchemy
.
Bạn có thể, trong một số bản phát hành sau này, hãy xóa hoàn toàn chức năng này, nhưng tôi sẽ để nó ở trạng thái này làm biển hiệu.
Bạn đã đề cập bằng cách sử dụng roxygen. Khi bạn thực hiện chuyển đổi đầu tiên thành không dùng nữa, bạn có thể thay đổi @rdname thành gói không dùng nữa, thêm dòng ở đầu mô tả cho biết nó không còn được dùng nữa, thêm hàm mới vào @seealso. Khi nó thay đổi không còn tồn tại, hãy thay đổi @rdname thành gói không còn tồn tại.
Trong trường hợp chuyển đổi tên hàm quá dài thành các phiên bản ngắn hơn, tôi khuyên bạn nên chỉ xuất cả hai tên dưới dạng hàm giống nhau (xem nhận xét của @ Brandon). Điều này sẽ cho phép mã cũ tiếp tục hoạt động trong khi cung cấp cho người dùng mới một giải pháp thay thế thuận tiện hơn.
Trong tâm trí, lý do duy nhất để gắn thẻ thứ gì đó là .Deprecated
(xem @GSEE) sẽ là nếu bạn dự định thay đổi chức năng hoặc ngừng hỗ trợ một số tính năng trong bản phát hành trong tương lai. Nếu trường hợp này xảy ra, bạn có thể sử dụng .Defunct
hoặc .Deprecated
.
Tôi đoán câu trả lời "đúng" phụ thuộc vào những gì bạn muốn.Theo quan điểm của tôi:
- Vấn đề với cách tiếp cận của Jeff và Brandon là chỉ mục của bạn sẽ liệt kê cả tên hàm và không cho biết đó là tên ưa thích. Hơn nữa mà không có một số loại cuộc gọi .Drecrecated, người dùng thậm chí còn nhiều hơn không biết những gì cách ưa thích để gọi chức năng là.
- Vấn đề với cách tiếp cận của Brian là quá trình liệt kê nhiều chức năng không được chấp nhận đã không rõ ràng với tôi.
Vì vậy, hãy nhập ví dụ của tôi bên dưới. Ở một vị trí khác, tôi xác định các phiên bản 'tốt' của các hàm (ví dụ: thuật giả kim, latinSquareDigram). Ở đây tôi xác định tất cả các phiên bản cũ 'xấu' mà tôi muốn tạo ra cảnh báo không dùng nữa. Tôi theo cách tiếp cận của gói xe và thay đổi tất cả các cuộc gọi chức năng của tôi cho phiên bản không dùng nữa để sử dụng ... làm đối số. Điều này đã giúp tôi tránh được một loạt các câu lệnh @param lộn xộn. Tôi cũng đã sử dụng chỉ thị @name và @docType để đặt "yourPackageName-deprecated" xuất hiện trong chỉ mục. Có lẽ ai đó có cách tốt hơn để làm điều này?
Hiện tại, mỗi chức năng không được chấp nhận vẫn hiển thị trong chỉ mục, nhưng nó cho biết "Các chức năng không được chấp nhận trong gói yourPackageName" bên cạnh chúng và mọi cuộc gọi đến chúng đều tạo cảnh báo không dùng nữa. Để loại bỏ chúng khỏi chỉ mục, người dùng có thể bỏ chỉ thị @aliases, nhưng sau đó bạn sẽ có các đối tượng mã không có giấy tờ cấp người dùng, tôi lấy nó, là biểu mẫu không hợp lệ.
#' 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
tại sao điều này không có upvotes ?! Yêu nó! –
@ mathematics.coffee: Cảm ơn! Có lẽ vì tôi đã trả lời 8 tháng sau người chiến thắng bounty. :) Tôi đã thử những lời khuyên trên và không hài lòng với kết quả. Vì vậy, khi tôi cuối cùng đã có một kết quả tôi đã hài lòng với tôi đăng câu trả lời của tôi. – russellpierce
Tôi tìm thấy người chiến thắng tiền thưởng hữu ích, nhưng điều này chắc chắn thêm vào nó. Tôi cần thêm một chút tình yêu roxygen2. –
Tôi gặp sự cố này một thời gian và không thể tìm được giải pháp tốt. Sau đó, tôi tìm thấy điều này. Tuy nhiên, các câu trả lời ở trên quá phức tạp đối với trường hợp đơn giản mà người dùng chỉ muốn: 1) thêm bí danh để mã cũ không ngừng hoạt động, 2) bí danh phải hoạt động với tài liệu được cài sẵn và 3) nên được thực hiện với roxygen2.
Đầu tiên, thêm một bản sao của hàm:
old_function_name = new_function_name
Sau đó, nơi new_function_name() được định nghĩa, thêm vào roxygen2:
#' @export new_function_name old_function_name
#' @aliases old_function_name
Bây giờ chức năng cũ làm việc bởi vì nó chỉ là một bản sao của hàm mới và tài liệu hoạt động vì bạn thiết lập bí danh. Phiên bản cũ cũng được xuất bởi vì nó được bao gồm trong @export.
xem '? Không được chấp nhận' – GSee
@alias chỉ cho phép người dùng tìm tài liệu về chức năng thông qua trợ giúp? Tốt hơn là xác định cả nội tuyến và xuất cả cũ và mới. 'some_func <- new_func_name <- function (x)' và sử dụng chỉ thị @alias. Bạn sẽ cần '@export some_func new_fund_name' nếu bạn muốn cả hai đều nằm trong vùng tên. Xem không? Namespace_roclet. Đối với tôi nó không có vẻ như bạn đang thay đổi chức năng, chỉ thay đổi tên - vậy không được chấp nhận dường như không thực sự áp dụng. –
Cảm ơn bạn rất nhiều @BrandonBertelsen Tôi khuyên bạn nên đăng câu trả lời này để câu trả lời hữu ích cho người khác. – Maiasaura