From 0e7ff8bd6790fa97b60e4c2214adc2f8634dadf1 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Tue, 11 Jun 2019 16:01:59 +0200 Subject: [PATCH] Deprecate `prepend()` and `modify()` Closes #766 Part of tidyverse/purrr#320 --- NEWS.md | 8 +++ R/lifecycle-retired.R | 62 +++++++++++++++++++++++ R/lifecycle.R | 5 ++ R/vec-utils.R | 87 --------------------------------- man/lifecycle.Rd | 5 ++ man/modify.Rd | 41 ---------------- man/prepend.Rd | 36 +++++--------- tests/testthat/test-retired.R | 6 +++ tests/testthat/test-vec-utils.R | 6 --- 9 files changed, 99 insertions(+), 157 deletions(-) delete mode 100644 man/modify.Rd diff --git a/NEWS.md b/NEWS.md index 9d096c200d..6d263a2175 100644 --- a/NEWS.md +++ b/NEWS.md @@ -59,6 +59,14 @@ `"function"` (@richierocks, #735). +## Lifecycle + +* `modify()` and `prepend()` (two experimental functions marked as in + the questioning stage since rlang 0.3.0) are now deprecated. Vector + functions are now out of scope for rlang. They might be revived in + the vctrs or funs packages. + + # rlang 0.3.2 * Fixed protection issue reported by rchk. diff --git a/R/lifecycle-retired.R b/R/lifecycle-retired.R index 5b5c328ff2..5beb46b8aa 100644 --- a/R/lifecycle-retired.R +++ b/R/lifecycle-retired.R @@ -1474,6 +1474,68 @@ signal_soft_deprecated_along <- function(type, na, env = caller_env(2)) { )) } +#' Prepend a vector +#' +#' @description +#' +#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} +#' +#' Vector functions are now out of scope for rlang. They might be +#' revived in the vctrs or funs packages. +#' +#' +#' @keywords internal +#' +#' @param x the vector to be modified. +#' @param values to be included in the modified vector. +#' @param before a subscript, before which the values are to be appended. +#' @export +prepend <- function(x, values, before = 1) { + warn_deprecated_vector("prepend") + + n <- length(x) + stopifnot(before > 0 && before <= n) + + if (before == 1) { + c(values, x) + } else { + c(x[1:(before - 1)], values, x[before:n]) + } +} + +#' @rdname prepend +#' @param .x A vector to modify. +#' @param ... List of elements to merge into `.x`. Named elements +#' already existing in `.x` are used as replacements. Elements that +#' have new or no names are inserted at the end. These dots support +#' [tidy dots][tidy-dots] features. +#' @export +modify <- function(.x, ...) { + warn_deprecated_vector("modify") + + out <- as.list(.x) + args <- list2(...) + + args_nms <- names(args) + exists <- have_name(args) & args_nms %in% names(out) + + for (nm in args_nms[exists]) { + out[[nm]] <- args[[nm]] + } + + c(out, args[!exists]) +} + +warn_deprecated_vector <- function(fn) { + warn_deprecated(paste_line( + sprintf("`%s()` is deprecated as of rlang 0.4.0.", fn), + "", + "Vector tools are now out of scope for rlang to make it a more", + "focused package." + )) +} + + # Attributes ------------------------------------------------------- diff --git a/R/lifecycle.R b/R/lifecycle.R index c141960d21..d7a93023da 100644 --- a/R/lifecycle.R +++ b/R/lifecycle.R @@ -179,6 +179,11 @@ #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' +#' **Deprecated as of rlang 0.4.0** +#' +#' * [modify()] and [prepend()]. +#' +#' #' **Deprecated as of rlang 0.3.0** #' #' * [as_data_mask()]: `parent` argument diff --git a/R/vec-utils.R b/R/vec-utils.R index e0d99674f6..5ed0fabb96 100644 --- a/R/vec-utils.R +++ b/R/vec-utils.R @@ -1,90 +1,3 @@ -#' Prepend a vector -#' -#' @description -#' -#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} -#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} -#' -#' This is a companion to [base::append()] to help merging two lists -#' or atomic vectors. `prepend()` is a clearer semantic signal than -#' `c()` that a vector is to be merged at the beginning of another, -#' especially in a pipe chain. -#' -#' -#' @keywords internal -#' @section Life cycle: -#' -#' `prepend()` is in the qestioning stage. We are still figuring out -#' what vector tools belong in rlang. -#' -#' @param x the vector to be modified. -#' @param values to be included in the modified vector. -#' @param before a subscript, before which the values are to be appended. -#' -#' @return A merged vector. -#' @export -#' @examples -#' x <- as.list(1:3) -#' -#' append(x, "a") -#' prepend(x, "a") -#' prepend(x, list("a", "b"), before = 3) -prepend <- function(x, values, before = 1) { - n <- length(x) - stopifnot(before > 0 && before <= n) - - if (before == 1) { - c(values, x) - } else { - c(x[1:(before - 1)], values, x[before:n]) - } -} - -#' Modify a vector -#' -#' @description -#' -#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} -#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} -#' -#' This function merges a list of arguments into a vector. It always -#' returns a list. -#' -#' -#' @keywords internal -#' @section Life cycle: -#' -#' `modify()` is in the qestioning stage. We are still figuring out -#' what vector tools belong in rlang. -#' -#' @param .x A vector to modify. -#' @param ... List of elements to merge into `.x`. Named elements -#' already existing in `.x` are used as replacements. Elements that -#' have new or no names are inserted at the end. These dots support -#' [tidy dots][tidy-dots] features. -#' -#' @return A modified vector upcasted to a list. -#' @export -#' @examples -#' modify(c(1, b = 2, 3), 4, b = "foo") -#' -#' x <- list(a = 1, b = 2) -#' y <- list(b = 3, c = 4) -#' modify(x, splice(y)) -modify <- function(.x, ...) { - out <- as.list(.x) - args <- list2(...) - - args_nms <- names(args) - exists <- have_name(args) & args_nms %in% names(out) - - for (nm in args_nms[exists]) { - out[[nm]] <- args[[nm]] - } - - c(out, args[!exists]) -} - #' Increasing sequence of integers in an interval #' #' These helpers take two endpoints and return the sequence of all diff --git a/man/lifecycle.Rd b/man/lifecycle.Rd index b460f3fbe5..c271b0913b 100644 --- a/man/lifecycle.Rd +++ b/man/lifecycle.Rd @@ -164,6 +164,11 @@ like \code{quos()} is soft-deprecated. \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} +\strong{Deprecated as of rlang 0.4.0} +\itemize{ +\item \code{\link[=modify]{modify()}} and \code{\link[=prepend]{prepend()}}. +} + \strong{Deprecated as of rlang 0.3.0} \itemize{ \item \code{\link[=as_data_mask]{as_data_mask()}}: \code{parent} argument diff --git a/man/modify.Rd b/man/modify.Rd deleted file mode 100644 index 3a4a9c7e0d..0000000000 --- a/man/modify.Rd +++ /dev/null @@ -1,41 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vec-utils.R -\name{modify} -\alias{modify} -\title{Modify a vector} -\usage{ -modify(.x, ...) -} -\arguments{ -\item{.x}{A vector to modify.} - -\item{...}{List of elements to merge into \code{.x}. Named elements -already existing in \code{.x} are used as replacements. Elements that -have new or no names are inserted at the end. These dots support -\link[=tidy-dots]{tidy dots} features.} -} -\value{ -A modified vector upcasted to a list. -} -\description{ -\Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} -\Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} - -This function merges a list of arguments into a vector. It always -returns a list. -} -\section{Life cycle}{ - - -\code{modify()} is in the qestioning stage. We are still figuring out -what vector tools belong in rlang. -} - -\examples{ -modify(c(1, b = 2, 3), 4, b = "foo") - -x <- list(a = 1, b = 2) -y <- list(b = 3, c = 4) -modify(x, splice(y)) -} -\keyword{internal} diff --git a/man/prepend.Rd b/man/prepend.Rd index c5462d3c6a..0b1336b46a 100644 --- a/man/prepend.Rd +++ b/man/prepend.Rd @@ -1,10 +1,13 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vec-utils.R +% Please edit documentation in R/lifecycle-retired.R \name{prepend} \alias{prepend} +\alias{modify} \title{Prepend a vector} \usage{ prepend(x, values, before = 1) + +modify(.x, ...) } \arguments{ \item{x}{the vector to be modified.} @@ -12,31 +15,18 @@ prepend(x, values, before = 1) \item{values}{to be included in the modified vector.} \item{before}{a subscript, before which the values are to be appended.} -} -\value{ -A merged vector. -} -\description{ -\Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} -\Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} - -This is a companion to \code{\link[base:append]{base::append()}} to help merging two lists -or atomic vectors. \code{prepend()} is a clearer semantic signal than -\code{c()} that a vector is to be merged at the beginning of another, -especially in a pipe chain. -} -\section{Life cycle}{ +\item{.x}{A vector to modify.} -\code{prepend()} is in the qestioning stage. We are still figuring out -what vector tools belong in rlang. +\item{...}{List of elements to merge into \code{.x}. Named elements +already existing in \code{.x} are used as replacements. Elements that +have new or no names are inserted at the end. These dots support +\link[=tidy-dots]{tidy dots} features.} } +\description{ +\Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} -\examples{ -x <- as.list(1:3) - -append(x, "a") -prepend(x, "a") -prepend(x, list("a", "b"), before = 3) +Vector functions are now out of scope for rlang. They might be +revived in the vctrs or funs packages. } \keyword{internal} diff --git a/tests/testthat/test-retired.R b/tests/testthat/test-retired.R index aefb2df528..69e9768917 100644 --- a/tests/testthat/test-retired.R +++ b/tests/testthat/test-retired.R @@ -514,3 +514,9 @@ test_that("vector _along() ctors pick up names", { expect_identical(new_raw_along(x, toupper), set_names(raw(2), c("A", "B"))) expect_identical(new_list_along(x, toupper), list(A = NULL, B = NULL)) }) + +test_that("vector is modified", { + x <- c(1, b = 2, c = 3, 4) + out <- modify(x, 5, b = 20, splice(list(6, c = "30"))) + expect_equal(out, list(1, b = 20, c = "30", 4, 5, 6)) +}) diff --git a/tests/testthat/test-vec-utils.R b/tests/testthat/test-vec-utils.R index 2dc4e58e68..d9444cf42f 100644 --- a/tests/testthat/test-vec-utils.R +++ b/tests/testthat/test-vec-utils.R @@ -1,11 +1,5 @@ context("vec-utils") -test_that("vector is modified", { - x <- c(1, b = 2, c = 3, 4) - out <- modify(x, 5, b = 20, splice(list(6, c = "30"))) - expect_equal(out, list(1, b = 20, c = "30", 4, 5, 6)) -}) - test_that("seq2() creates increasing sequences", { expect_identical(seq2(2, 3), 2:3) expect_identical(seq2(3, 2), int())