25 Deprecation Guidelines
In the normal course of software development, functions, classes, methods, or data objects may need to be removed. Here are some guidelines for ensuring that this process is minimally disruptive to your users.
25.1 What to Deprecate?
Any function, class, method, data, or even package that is no longer used or needed.
25.2 When to Follow These Guidelines?
>|--- Bioconductor development cycle ---------------|>
>|--- o feature introduced --- o feature removed ---|>
Note that if you decide against using a function that you had introduced within the same development cycle, you may simply remove the function without following the standard function deprecation guidelines. It is expected that the devel branch be unstable and be subject to API changes without notice (though you may decide to communicate these changes to your users via the Bioconductor support site).
>| Bioconductor RELEASE_X_Y | Bioconductor development cycle |>
>|-- o feature introduced --|----- o feature removed --------|>
However, if a function was published in at least one release version of Bioconductor, these guidelines must be followed. The process of removing a feature such as a function, class, method, or exported package object takes approximately three release cycles (about 18 months).
25.3 How To Deprecate A Function
25.3.1 Step 1: Deprecate the function
When you first decide to deprecate a function, you should mark it as
deprecated in the devel branch. Do this by calling .Deprecated()
inside the function. To do this, you must provide a replacement function
which should be used in place of the old function. Example:
myOldFunc <- function()
{
.Deprecated("myNewFunc")
## use new function, or remainder of myOldFunc
}
This causes a warning to be emitted whenever a user calls
myOldFunc()
. See ?.Deprecated
for more information.
Indicate in the man page of the old function that it has been deprecated, and suggest a replacement function. Be sure the old function is not called in man page examples or vignette code chunks; R CMD check should report this.
\name{MyPkg-deprecated}
\alias{MyPkg-deprecated}
\title{Deprecated functions in package \sQuote{MyPkg}}
\description{
These functions are provided for compatibility with older versions
of \sQuote{MyPkg} only, and will be defunct at the next release.
}
\details{
The following functions are deprecated and will be made defunct; use
the replacement indicated below:
\itemize{
\item{myOldFunc: \code{\link{newFunc}}}
}
}
25.3.2 Step 2: Mark the function as defunct
In the next release cycle, after your function has been deprecated, it must be made defunct in the devel branch. This means a call to the old function will return an informative error but not run any additional code. Example:
myOldFunc <- function()
{
.Defunct("myNewFunc")
}
See ?Defunct
for more information.
Remove the documentation of the defunct function, and add to a man page such as the following:
\name{MyPkg-defunct}
\alias{myOldFunc}
\title{Defunct functions in package \sQuote{pkg}}
\description{These functions are defunct and no longer available.}
\details{
Defunct functions are: \code{myOldFunc}
}
25.3.3 Step 3: Remove the function
In the next release cycle, after your function has been marked as defunct, remove it entirely from your package R code and NAMESPACE in the devel branch. Also remove any man page content that documents the function.
Leave the man page from the previous step in place so that
help("MyPkg-defunct")
still shows the list of defunct functions and their appropriate replacements.
25.4 How To Deprecate An S3 Dataset
25.4.1 Step 1 - Create an S3 deprecation class
The initial step of deprecating a dataset is to signal to users that the
dataset will no longer be used. Alert the user with a warning
message added to
its print
method. To do this, first add the deprecation class to the dataset
object. Note that the class name here is arbitrary but it should be descriptive:
class(pkgDataset) <- c("DeprecatedData", class(pkgDataset))
Then serialize the class as an R object so that it can be loaded in the package:
save(pkgDataset, file = "data/pkgDataset.rda")
or with usethis
:
usethis::use_data(pkgDataset, overwrite = TRUE)
25.4.2 Step 2 - Create a print method
Then create a print method for the new class that will print the warning message:
print.DeprecatedData <- function(x, ...) {
warning("'pkgDataset' dataset is deprecated; see '?newData'")
NextMethod()
}
It is useful to guide the user to the replacement dataset or functionality
that will replace the data in the warning
message. Note that this method
should be exported in the package’s NAMESPACE
file.
25.5 How to Deprecate An S4 Dataset
25.5.1 Step 1 - Create an S4 deprecation class
With S4, the process is similar to S3, but we need to create a new class
that inherits from the original class with setClass
. The class name here
is arbitrary but should be descriptive:
.DeprecatedData <-
setClass("DeprecatedData", contains = "S4Class")
The setClass
call creates a generator function which we can then use
to create an instance of the new class from the old object:
myS4DataObject <- .DeprecatedData(myS4DataObject)
We then serialize the object to disk so that it can be loaded in the package:
save(myS4DataObject, file = "data/myS4DataObject.rda")
or by using usethis
:
usethis::use_data(myS4DataObject, overwrite = TRUE)
25.5.2 Step 2 - Create a show method
Create a show
method for the new class that will produce a warning message:
setMethod("show", "DeprecatedData", function(object) {
warning("This dataset is deprecated; see '?newData'")
callNextMethod()
})
Note that this method should be exported in the package’s NAMESPACE
and
the show
generic should be imported from the methods
package.
Note that steps 3 and 4 are the same as for S3 datasets.
25.6 How to Deprecate a Package
Please see section on Package End of Life Policy