diff --git a/NEWS.md b/NEWS.md index 3e31d13d6..e2212163a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,7 @@ * `eval_code` uses `evaluate::evaluate` and stores returned outputs in the code's attribute. * Refactor `eval_code` method signature to allow for more flexibility when extending the `eval_code`/`within` functions. +* `get_var(qenv, ...)` and `join(qenv, ...)` were hard deprecated. # teal.code 0.6.1 diff --git a/R/qenv-get_outputs.R b/R/qenv-get_outputs.R index 2aa626165..98a4ae2f3 100644 --- a/R/qenv-get_outputs.R +++ b/R/qenv-get_outputs.R @@ -1,6 +1,7 @@ #' Get outputs #' -#' @description +#' @description `r lifecycle::badge("experimental")` +#' #' `eval_code` evaluates code silently so plots and prints don't show up in the console or graphic devices. #' If one wants to use an output outside of the `qenv` (e.g. use a graph in `renderPlot`) then use `get_outputs`. #' @param object (`qenv`) diff --git a/R/qenv-get_var.R b/R/qenv-get_var.R index bdadaca43..a4d6fccb8 100644 --- a/R/qenv-get_var.R +++ b/R/qenv-get_var.R @@ -5,45 +5,12 @@ #' Instead of [get_var()] use native \R operators/functions: #' `x[[name]]`, `x$name` or [get()]: #' -#' Retrieve variables from the `qenv` environment. -#' -#' @param object,x (`qenv`) -#' @param var,i (`character(1)`) variable name. -#' -#' @return The value of required variable (`var`) within `qenv` object. -#' -#' @examples -#' q <- qenv() -#' q1 <- eval_code(q, code = quote(a <- 1)) -#' q2 <- eval_code(q1, code = "b <- a") -#' get_var(q2, "b") -#' -#' @aliases get_var,qenv,character-method -#' @aliases get_var,qenv.error,ANY-method +#' @param ... function is deprecated. +#' @param x (`qenv`) +#' @param i (`character(1)`) variable name. #' #' @export -setGeneric("get_var", function(object, var) { - dev_suppress(object) - standardGeneric("get_var") -}) - -setMethod("get_var", signature = c("qenv", "character"), function(object, var) { - lifecycle::deprecate_soft("0.6.0", "get_var()", "base::get()") - tryCatch( - get(var, envir = object@.xData, inherits = FALSE), - error = function(e) { - message(conditionMessage(e)) - NULL - } - ) -}) - -setMethod("get_var", signature = c("qenv.error", "ANY"), function(object, var) { - stop(errorCondition( - list(message = conditionMessage(object)), - class = c("validation", "try-error", "simpleError") - )) -}) +get_var <- function(...) lifecycle::deprecate_stop("0.6.0", "get_var()", "base::get()") #' @rdname get_var #' @export diff --git a/R/qenv-join.R b/R/qenv-join.R index 66843fa5c..f5c467a75 100644 --- a/R/qenv-join.R +++ b/R/qenv-join.R @@ -1,152 +1,13 @@ #' Join `qenv` objects #' #' @description -#' Checks and merges two `qenv` objects into one `qenv` object. +#' `r lifecycle::badge("deprecated")` +#' Instead of [join()] use [c()]. #' -#' The `join()` function is superseded by the `c()` function. -#' -#' @details -#' Any common code at the start of the `qenvs` is only placed once at the start of the joined `qenv`. -#' This allows consistent behavior when joining `qenvs` which share a common ancestor. -#' See below for an example. -#' -#' There are some situations where `join()` cannot be properly performed, such as these three scenarios: -#' 1. Both `qenv` objects contain an object of the same name but are not identical. -#' -#' Example: -#' -#' ```r -#' x <- eval_code(qenv(), expression(mtcars1 <- mtcars)) -#' y <- eval_code(qenv(), expression(mtcars1 <- mtcars['wt'])) -#' -#' z <- c(x, y) -#' # Error message will occur -#' ``` -#' In this example, `mtcars1` object exists in both `x` and `y` objects but the content are not identical. -#' `mtcars1` in the `x qenv` object has more columns than `mtcars1` in the `y qenv` object (only has one column). -#' -#' 2. `join()` will look for identical code elements in both `qenv` objects. -#' The index position of these code elements must be the same to determine the evaluation order. -#' Otherwise, `join()` will throw an error message. -#' -#' Example: -#' ```r -#' common_q <- eval_code(qenv(), expression(v <- 1)) -#' x <- eval_code( -#' common_q, -#' "x <- v" -#' ) -#' y <- eval_code( -#' common_q, -#' "y <- v" -#' ) -#' z <- eval_code( -#' y, -#' "z <- v" -#' ) -#' q <- c(x, y) -#' join_q <- c(q, z) -#' # Error message will occur -#' -#' # Check the order of evaluation based on the id slot -#' ``` -#' The error occurs because the index position of common code elements in the two objects is not the same. -#' -#' 3. The usage of temporary variable in the code expression could cause `join()` to fail. -#' -#' Example: -#' ```r -#' common_q <- qenv() -#' x <- eval_code( -#' common_q, -#' "x <- numeric(0) -#' for (i in 1:2) { -#' x <- c(x, i) -#' }" -#' ) -#' y <- eval_code( -#' common_q, -#' "y <- numeric(0) -#' for (i in 1:3) { -#' y <- c(y, i) -#' }" -#' ) -#' q <- join(x,y) -#' # Error message will occur -#' -#' # Check the value of temporary variable i in both objects -#' x$i # Output: 2 -#' y$i # Output: 3 -#' ``` -#' `c()` fails to provide a proper result because of the temporary variable `i` exists -#' in both objects but has different value. -#' To fix this, we can set `i <- NULL` in the code expression for both objects. -#' ```r -#' common_q <- qenv() -#' x <- eval_code( -#' common_q, -#' "x <- numeric(0) -#' for (i in 1:2) { -#' x <- c(x, i) -#' } -#' # dummy i variable to fix it -#' i <- NULL" -#' ) -#' y <- eval_code( -#' common_q, -#' "y <- numeric(0) -#' for (i in 1:3) { -#' y <- c(y, i) -#' } -#' # dummy i variable to fix it -#' i <- NULL" -#' ) -#' q <- c(x,y) -#' ``` -#' -#' @param x (`qenv`) -#' @param y (`qenv`) -#' -#' @return `qenv` object. -#' -#' @examples -#' q <- qenv() -#' q1 <- eval_code(q, expression(iris1 <- iris, mtcars1 <- mtcars)) -#' q2 <- q1 -#' q1 <- eval_code(q1, "iris2 <- iris") -#' q2 <- eval_code(q2, "mtcars2 <- mtcars") -#' qq <- join(q1, q2) -#' cat(get_code(qq)) -#' -#' common_q <- eval_code(q, quote(x <- 1)) -#' y_q <- eval_code(common_q, quote(y <- x * 2)) -#' z_q <- eval_code(common_q, quote(z <- x * 3)) -#' join_q <- join(y_q, z_q) -#' # get_code only has "x <- 1" occurring once -#' cat(get_code(join_q)) -#' -#' @include qenv-errors.R +#' @param ... function is deprecated. #' #' @name join #' @rdname join -#' @aliases join,qenv,qenv-method -#' @aliases join,qenv,qenv.error-method -#' @aliases join,qenv.error,ANY-method #' #' @export -setGeneric("join", function(x, y) standardGeneric("join")) - -setMethod("join", signature = c("qenv", "qenv"), function(x, y) { - lifecycle::deprecate_soft("0.6.0", "join()", "c()") - c(x, y) -}) - -setMethod("join", signature = c("qenv", "qenv.error"), function(x, y) { - lifecycle::deprecate_soft("0.6.0", "join()", "c()") - y -}) - -setMethod("join", signature = c("qenv.error", "ANY"), function(x, y) { - lifecycle::deprecate_soft("0.6.0", "join()", "c()") - x -}) +join <- function(...) lifecycle::deprecate_stop("0.6.0", "join()", "c()") diff --git a/man/get_outputs.Rd b/man/get_outputs.Rd index e838cecbd..eae96bab7 100644 --- a/man/get_outputs.Rd +++ b/man/get_outputs.Rd @@ -14,6 +14,8 @@ get_outputs(object) list of outputs generated in a `qenv`` } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + \code{eval_code} evaluates code silently so plots and prints don't show up in the console or graphic devices. If one wants to use an output outside of the \code{qenv} (e.g. use a graph in \code{renderPlot}) then use \code{get_outputs}. } diff --git a/man/get_var.Rd b/man/get_var.Rd index ff8b71207..dc41dec9a 100644 --- a/man/get_var.Rd +++ b/man/get_var.Rd @@ -2,34 +2,22 @@ % Please edit documentation in R/qenv-get_var.R \name{get_var} \alias{get_var} -\alias{get_var,qenv,character-method} -\alias{get_var,qenv.error,ANY-method} \alias{[[.qenv.error} \title{Get object from \code{qenv}} \usage{ -get_var(object, var) +get_var(...) \method{[[}{qenv.error}(x, i) } \arguments{ -\item{object, x}{(\code{qenv})} +\item{...}{function is deprecated.} -\item{var, i}{(\code{character(1)}) variable name.} -} -\value{ -The value of required variable (\code{var}) within \code{qenv} object. +\item{x}{(\code{qenv})} + +\item{i}{(\code{character(1)}) variable name.} } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Instead of \code{\link[=get_var]{get_var()}} use native \R operators/functions: \code{x[[name]]}, \code{x$name} or \code{\link[=get]{get()}}: - -Retrieve variables from the \code{qenv} environment. -} -\examples{ -q <- qenv() -q1 <- eval_code(q, code = quote(a <- 1)) -q2 <- eval_code(q1, code = "b <- a") -get_var(q2, "b") - } diff --git a/man/join.Rd b/man/join.Rd index 4a495524c..252d8a36c 100644 --- a/man/join.Rd +++ b/man/join.Rd @@ -4,132 +4,20 @@ \alias{c.qenv} \alias{c.qenv.error} \alias{join} -\alias{join,qenv,qenv-method} -\alias{join,qenv,qenv.error-method} -\alias{join,qenv.error,ANY-method} \title{Join \code{qenv} objects} \usage{ \method{c}{qenv}(...) \method{c}{qenv.error}(...) -join(x, y) +join(...) } \arguments{ -\item{...}{(\code{qenv} or \code{qenv.error}).} - -\item{x}{(\code{qenv})} - -\item{y}{(\code{qenv})} -} -\value{ -\code{qenv} object. +\item{...}{function is deprecated.} } \description{ -Checks and merges two \code{qenv} objects into one \code{qenv} object. - -The \code{join()} function is superseded by the \code{c()} function. -} -\details{ -Any common code at the start of the \code{qenvs} is only placed once at the start of the joined \code{qenv}. -This allows consistent behavior when joining \code{qenvs} which share a common ancestor. -See below for an example. - -There are some situations where \code{join()} cannot be properly performed, such as these three scenarios: -\enumerate{ -\item Both \code{qenv} objects contain an object of the same name but are not identical. - -Example: - -\if{html}{\out{
}}\preformatted{x <- eval_code(qenv(), expression(mtcars1 <- mtcars)) -y <- eval_code(qenv(), expression(mtcars1 <- mtcars['wt'])) - -z <- c(x, y) -# Error message will occur -}\if{html}{\out{
}} - -In this example, \code{mtcars1} object exists in both \code{x} and \code{y} objects but the content are not identical. -\code{mtcars1} in the \verb{x qenv} object has more columns than \code{mtcars1} in the \verb{y qenv} object (only has one column). -\item \code{join()} will look for identical code elements in both \code{qenv} objects. -The index position of these code elements must be the same to determine the evaluation order. -Otherwise, \code{join()} will throw an error message. - -Example: - -\if{html}{\out{
}}\preformatted{common_q <- eval_code(qenv(), expression(v <- 1)) -x <- eval_code( - common_q, - "x <- v" -) -y <- eval_code( - common_q, - "y <- v" -) -z <- eval_code( - y, - "z <- v" -) -q <- c(x, y) -join_q <- c(q, z) -# Error message will occur - -# Check the order of evaluation based on the id slot -}\if{html}{\out{
}} - -The error occurs because the index position of common code elements in the two objects is not the same. -\item The usage of temporary variable in the code expression could cause \code{join()} to fail. - -Example: - -\if{html}{\out{
}}\preformatted{common_q <- qenv() -x <- eval_code( - common_q, - "x <- numeric(0) - for (i in 1:2) \{ - x <- c(x, i) - \}" -) -y <- eval_code( - common_q, - "y <- numeric(0) - for (i in 1:3) \{ - y <- c(y, i) - \}" -) -q <- join(x,y) -# Error message will occur - -# Check the value of temporary variable i in both objects -x$i # Output: 2 -y$i # Output: 3 -}\if{html}{\out{
}} - -\code{c()} fails to provide a proper result because of the temporary variable \code{i} exists -in both objects but has different value. -To fix this, we can set \code{i <- NULL} in the code expression for both objects. - -\if{html}{\out{
}}\preformatted{common_q <- qenv() -x <- eval_code( - common_q, - "x <- numeric(0) - for (i in 1:2) \{ - x <- c(x, i) - \} - # dummy i variable to fix it - i <- NULL" -) -y <- eval_code( - common_q, - "y <- numeric(0) - for (i in 1:3) \{ - y <- c(y, i) - \} - # dummy i variable to fix it - i <- NULL" -) -q <- c(x,y) -}\if{html}{\out{
}} -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} +Instead of \code{\link[=join]{join()}} use \code{\link[=c]{c()}}. } \examples{ q <- qenv() @@ -142,19 +30,4 @@ q2 <- within(q1, mtcars2 <- mtcars) qq <- c(q1, q2) cat(get_code(qq)) -q <- qenv() -q1 <- eval_code(q, expression(iris1 <- iris, mtcars1 <- mtcars)) -q2 <- q1 -q1 <- eval_code(q1, "iris2 <- iris") -q2 <- eval_code(q2, "mtcars2 <- mtcars") -qq <- join(q1, q2) -cat(get_code(qq)) - -common_q <- eval_code(q, quote(x <- 1)) -y_q <- eval_code(common_q, quote(y <- x * 2)) -z_q <- eval_code(common_q, quote(z <- x * 3)) -join_q <- join(y_q, z_q) -# get_code only has "x <- 1" occurring once -cat(get_code(join_q)) - } diff --git a/tests/testthat/test-qenv_get_var.R b/tests/testthat/test-qenv_get_var.R index 89b31c6ef..8117a5ab8 100644 --- a/tests/testthat/test-qenv_get_var.R +++ b/tests/testthat/test-qenv_get_var.R @@ -1,45 +1,39 @@ -testthat::test_that("get_var, `$` and `[[` return error if object is qenv.error", { +testthat::test_that("`$` and `[[` return error if object is qenv.error", { q <- eval_code(qenv(), quote(x <- 1)) q <- eval_code(q, quote(y <- w * x)) - testthat::expect_error(get_var(q, "x"), "when evaluating qenv code") testthat::expect_error(q[["x"]], "when evaluating qenv code") testthat::expect_error(q$x, "when evaluating qenv code") }) -testthat::test_that("get_var, `$` and `[[` return object from qenv environment", { +testthat::test_that("`$` and `[[` return object from qenv environment", { q <- eval_code(qenv(), quote(x <- 1)) q <- eval_code(q, quote(y <- 5 * x)) - lifecycle::expect_deprecated(testthat::expect_equal(get_var(q, "y"), 5)) testthat::expect_equal(q[["x"]], 1) testthat::expect_equal(q$x, 1) }) -testthat::test_that("get_var, `$` and `[[` return NULL if object not in qenv environment", { +testthat::test_that("`$` and `[[` return NULL if object not in qenv environment", { q <- eval_code(qenv(), quote(x <- 1)) q <- eval_code(q, quote(y <- 5 * x)) - testthat::expect_message( - testthat::expect_null(get_var(q, "z")) - ) testthat::expect_null(q[["w"]]) testthat::expect_null(q$w) }) -testthat::test_that("get_var, `$` and `[[` only returns objects from qenv, not parent environment(s)", { +testthat::test_that("`$` and `[[` only returns objects from qenv, not parent environment(s)", { q <- qenv() new_env <- new.env(parent = parent.env(q)) new_env$an_object <- 2 - testthat::expect_null(get_var(q, "an_object")) testthat::expect_null(q[["an_object"]]) testthat::expect_null(q$an_object) }) -testthat::test_that("get_var, `$` and `[[` only returns objects from qenv, not .GlobalEnv", { +testthat::test_that("`$` and `[[` only returns objects from qenv, not .GlobalEnv", { if (is.null(.GlobalEnv)) { withr::defer(rm("an_object", envir = .GlobalEnv)) } else { @@ -49,7 +43,6 @@ testthat::test_that("get_var, `$` and `[[` only returns objects from qenv, not . .GlobalEnv$an_object <- iris # nolint: object_name. q <- qenv() - testthat::expect_null(get_var(q, "iris")) testthat::expect_null(q[["iris"]]) testthat::expect_null(q$iris) })