To deprecate a class, change new_class() to deprecated_class() in its
definition and supply when. Keep its existing parent, properties,
constructor, and validator, and keep exporting it under the same name.
Calling the constructor warns, then constructs an instance of the
deprecated class. Using it in method signatures, parent, property
classes, or new_external_class() references does not warn.
Property defaults generated before deprecation can still signal; see
"Installed property defaults" below.
Supply new to recommend another class in the warning. This
changes the message only: Dog() still creates a Dog, even if the
warning recommends Pet(). Methods for Dog remain methods for Dog.
To register a method for both classes, use Dog | Pet as its signature.
Omit new to deprecate the class without recommending another.
Usage
deprecated_class(
name,
...,
when,
new = NULL,
method = c("base", "lifecycle(warn)", "lifecycle(stop)")
)Arguments
- name
The name of the class, as a string. Assign the result to a variable with this name, most easily with :=.
- ...
Named arguments passed to
new_class(), such asparent,properties,constructor, andvalidator.- when
The package version when the deprecation began, e.g.
"1.2.0".- new
An S7 class to recommend in the warning, or
NULLto give no recommendation. It does not affect construction or dispatch.- method
How to signal the deprecation:
"base"(the default): a.Deprecated()-style warning."lifecycle(warn)":lifecycle::deprecate_warn(), a warning that's only displayed once every eight hours."lifecycle(stop)":lifecycle::deprecate_stop(), an error.
The lifecycle options require the lifecycle package to be installed, and to be a dependency of your package.
Installed subclasses
Adding deprecation to an otherwise unchanged class does not require rebuilding packages that define subclasses. Existing instances and subclasses continue matching methods for the deprecated class.
The helper does not convert existing or saved objects to new,
or update installed subclasses if you also change the class definition.
Changes to the parent, properties, constructor, or validator need the same
compatibility considerations as changes to a non-deprecated class.
Installed property defaults
A downstream package installed before deprecation can retain a property default that calls the constructor directly. For example:
After upstream deprecates Foo, Box() can warn, or error with
method = "lifecycle(stop)". Rebuild and reinstall the downstream package
against the updated upstream to generate a silent default. Defaults
generated from new_external_class() references stay silent without
rebuilding.
Explicitly written constructor calls, including calls in a property's
default or a custom constructor, still signal after rebuilding.
See also
deprecated_generic() and deprecated_property() to deprecate
other parts of your API.
Examples
# Recommend Pet() while keeping Dog() working:
Pet := new_class(properties = list(name = class_character))
Dog := deprecated_class(
properties = list(name = class_character),
new = Pet,
when = "2.0.0"
)
Dog(name = "Fido") # warns and creates a Dog
#> Warning: `Dog()` was deprecated in version 2.0.0.
#> Please use `Pet()` instead.
#> <Dog>
#> @ name: chr "Fido"
Pet(name = "Fido") # creates a Pet without warning
#> <Pet>
#> @ name: chr "Fido"
# Existing methods and subclasses still use Dog:
speak := new_generic("x")
method(speak, Dog) <- function(x) "Woof!"
Puppy := new_class(parent = Dog)
speak(Puppy(name = "Rex"))
#> [1] "Woof!"
# A method can support both classes:
method(speak, Dog | Pet) <- function(x) x@name
#> Overwriting method speak(<Dog>)
speak(Pet(name = "Rex"))
#> [1] "Rex"
# A class deprecated without a replacement:
Cat := deprecated_class(
properties = list(lives = class_double),
when = "3.0.0"
)
Cat(lives = 9)
#> Warning: `Cat()` was deprecated in version 3.0.0.
#> <Cat>
#> @ lives: num 9