From 97b5092e0949ffd50a2bc10776e77bdc8cf2eb53 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Wed, 18 Dec 2024 09:33:37 +0100 Subject: [PATCH 01/21] Remove old deprecation --- vignettes/teal-code.Rmd | 2 -- 1 file changed, 2 deletions(-) diff --git a/vignettes/teal-code.Rmd b/vignettes/teal-code.Rmd index aee2c842..1d205267 100644 --- a/vignettes/teal-code.Rmd +++ b/vignettes/teal-code.Rmd @@ -18,5 +18,3 @@ In this context, the `qenv` object within the `teal.code` package emerges as a p It's worth noting that there exists a public [`shinymeta`](https://github.com/rstudio/shinymeta) R package by `RStudio`, offering similar functionality. However, integrating `shinymeta` into `teal` modules poses challenges. Consequently, we recommend the use of `qenv` for teal-based applications. For comprehensive insights, please refer to the [`qenv` vignette](https://insightsengineering.github.io/teal.code/latest-tag/articles/qenv.html). - -Important Note: The legacy approach to handling reproducibility, known as `chunks`, has been deprecated. We strongly advocate for the adoption of `qenv` as its successor. From 9bb5da155749412e4ee0796c66345a54a3133c56 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Wed, 18 Dec 2024 10:50:24 +0100 Subject: [PATCH 02/21] emphasizing environment inheritance --- R/qenv-eval_code.R | 4 ++++ man/qenv.Rd | 4 ++++ vignettes/qenv.Rmd | 17 ++++++++--------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/R/qenv-eval_code.R b/R/qenv-eval_code.R index e8166b47..9be04dd8 100644 --- a/R/qenv-eval_code.R +++ b/R/qenv-eval_code.R @@ -3,6 +3,10 @@ #' @details #' `eval_code()` evaluates given code in the `qenv` environment and appends it to the `code` slot. #' Thus, if the `qenv` had been instantiated empty, contents of the environment are always a result of the stored code. +#' The `qenv` object is immutable, even though it inherits from the environment class, which is typically mutable by +#' design. This means that each code evaluation does not modify the original `qenv` object directly. Instead, every +#' code evaluation creates a new `qenv` object that reflects the result of the changes, leaving the original object +#' unchanged. #' #' @param object (`qenv`) #' @param code (`character`, `language` or `expression`) code to evaluate. diff --git a/man/qenv.Rd b/man/qenv.Rd index 0d45c8f3..a9360e56 100644 --- a/man/qenv.Rd +++ b/man/qenv.Rd @@ -75,6 +75,10 @@ Any changes must be made by evaluating code in it with \code{eval_code} or \code \code{eval_code()} evaluates given code in the \code{qenv} environment and appends it to the \code{code} slot. Thus, if the \code{qenv} had been instantiated empty, contents of the environment are always a result of the stored code. +The \code{qenv} object is immutable, even though it inherits from the environment class, which is typically mutable by +design. This means that each code evaluation does not modify the original \code{qenv} object directly. Instead, every +code evaluation creates a new \code{qenv} object that reflects the result of the changes, leaving the original object +unchanged. \code{x[[name]]}, \code{x$name} and \code{get(name, x)} are generic \R operators to access the objects in the environment. See [\code{[[}] for more details. diff --git a/vignettes/qenv.Rmd b/vignettes/qenv.Rmd index 2db54b4b..70c5ce81 100644 --- a/vignettes/qenv.Rmd +++ b/vignettes/qenv.Rmd @@ -10,7 +10,7 @@ vignette: > ## Introduction to `qenv` -A `qenv` is an R object which contains code and an environment and can be used to create reproducible outputs. +A `qenv` is an `environment` which contains data and a code used to create data. ### Initialization @@ -26,14 +26,13 @@ print(empty_qenv) ### `qenv` basic usage -The `eval_code()` function executes code within a `qenv` environment, yielding a new `qenv` object as the output. +`qenv` object is a locked `environment`. To modify the data use `eval_code` to execute R code +within the environment, yielding a new `qenv` object as the output. ```{r} # evaluate code in qenv my_qenv <- eval_code(empty_qenv, "x <- 2") print(my_qenv) -as.environment(my_qenv) - q1 <- eval_code(my_qenv, "y <- x * 2") q1 <- eval_code(q1, "z <- y * 2") @@ -47,16 +46,14 @@ print(q1) names(q1) ``` -The same result can be achieved with the `within` method for the `qenv` class. +The same result can be achieved with the `within` method. + ```{r} q2 <- within(my_qenv, y <- x * 2) q2 <- within(q2, z <- y * 2) print(q2) ``` - - - To extract objects from a `qenv`, use `[[`; this is particularly useful for displaying them in a `shiny` app. You can retrieve the code used to generate the `qenv` using the `get_code()` function. ```{r} @@ -66,8 +63,10 @@ cat(get_code(q2)) ``` ### Substitutions + In some cases, one may want to substitute some elements of the code before evaluation. Consider a case when a subset of `iris` is defined by an input value. + ```{r} q <- qenv() q <- eval_code(q, quote(i <- subset(iris, Species == "setosa"))) @@ -87,6 +86,7 @@ summary(q[["iii"]]$Species) ``` A more convenient way to pass code with substitution is to use the `within` method. + ```{r} qq <- qenv() qq <- within(qq, i <- subset(iris, Species == "setosa")) @@ -101,7 +101,6 @@ summary(qq[["iii"]]$Species) See `?qenv` for more details. - ### Combining `qenv` objects Given a pair of `qenv` objects, you may be able to "join" them, creating a new `qenv` object encompassing the union of both environments, along with the requisite code for reproduction: From e90d07b5499f4dc2494ce0a15670f42fe217f3a9 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Wed, 18 Dec 2024 10:54:45 +0100 Subject: [PATCH 03/21] qenv characteristics --- vignettes/qenv.Rmd | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vignettes/qenv.Rmd b/vignettes/qenv.Rmd index 70c5ce81..5e13ae10 100644 --- a/vignettes/qenv.Rmd +++ b/vignettes/qenv.Rmd @@ -10,7 +10,11 @@ vignette: > ## Introduction to `qenv` -A `qenv` is an `environment` which contains data and a code used to create data. +A `qenv` object inherits from the `environment` class, behaves like an environment, and has the following characteristics: + +- The environment is locked, and data modification is only possible through the `eval_code()` and `within()` functions. +- It stores metadata about the code used to create the data. +- Is immutable which means that each code evaluation does not modify the original `qenv` object directly. ### Initialization @@ -26,8 +30,7 @@ print(empty_qenv) ### `qenv` basic usage -`qenv` object is a locked `environment`. To modify the data use `eval_code` to execute R code -within the environment, yielding a new `qenv` object as the output. +To modify the data use `eval_code` to execute R code within the environment, yielding a new `qenv` object as the output. ```{r} # evaluate code in qenv From 5dc7720827a7ef371924bf07df41237256250143 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Wed, 18 Dec 2024 12:12:28 +0100 Subject: [PATCH 04/21] qenv characteristics --- R/qenv-constructor.R | 14 ++++++++++++-- man/qenv.Rd | 17 +++++++++++++++-- vignettes/qenv.Rmd | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/R/qenv-constructor.R b/R/qenv-constructor.R index b022db72..0e1b5712 100644 --- a/R/qenv-constructor.R +++ b/R/qenv-constructor.R @@ -11,8 +11,18 @@ #' #' @details #' -#' `qenv()` instantiates a `qenv` with an empty environment. -#' Any changes must be made by evaluating code in it with `eval_code` or `within`, thereby ensuring reproducibility. +#' `qenv()` instantiates a with an empty `qenv` environment. +#' +#' @section `qenv` characteristics: +#' +#' A `qenv` inherits from the `environment` class, behaves like an environment, and has the +#' following characteristics: +#' +#' - The environment is locked, and data modification is only possible through the `eval_code()` +#' and `within()` functions. +#' - It stores metadata about the code used to create the data. +#' - Is immutable which means that each code evaluation does not modify the original `qenv` object +#' directly. #' #' @name qenv #' diff --git a/man/qenv.Rd b/man/qenv.Rd index a9360e56..00ba2df4 100644 --- a/man/qenv.Rd +++ b/man/qenv.Rd @@ -70,8 +70,7 @@ the \code{all.names = TRUE}, which will show all objects. Create a \code{qenv} object and evaluate code in it to track code history. } \details{ -\code{qenv()} instantiates a \code{qenv} with an empty environment. -Any changes must be made by evaluating code in it with \code{eval_code} or \code{within}, thereby ensuring reproducibility. +\code{qenv()} instantiates a with an empty \code{qenv} environment. \code{eval_code()} evaluates given code in the \code{qenv} environment and appends it to the \code{code} slot. Thus, if the \code{qenv} had been instantiated empty, contents of the environment are always a result of the stored code. @@ -92,6 +91,20 @@ It is a method for the \code{base} generic that wraps \code{eval_code} to provid through the \code{...} argument: as \code{name:value} pairs are passed to \code{...}, \code{name} in \code{expr} will be replaced with \code{value}. } +\section{\code{qenv} characteristics}{ + + +A \code{qenv} inherits from the \code{environment} class, behaves like an environment, and has the +following characteristics: +\itemize{ +\item The environment is locked, and data modification is only possible through the \code{eval_code()} +and \code{within()} functions. +\item It stores metadata about the code used to create the data. +\item Is immutable which means that each code evaluation does not modify the original \code{qenv} object +directly. +} +} + \section{Subsetting}{ \code{x[names]} subsets objects in \code{qenv} environment and limit the code to the necessary needed to build limited objects. diff --git a/vignettes/qenv.Rmd b/vignettes/qenv.Rmd index 5e13ae10..e2493fb4 100644 --- a/vignettes/qenv.Rmd +++ b/vignettes/qenv.Rmd @@ -10,7 +10,7 @@ vignette: > ## Introduction to `qenv` -A `qenv` object inherits from the `environment` class, behaves like an environment, and has the following characteristics: +A `qenv` inherits from the `environment` class, behaves like an environment, and has the following characteristics: - The environment is locked, and data modification is only possible through the `eval_code()` and `within()` functions. - It stores metadata about the code used to create the data. From 04cb357ede6429cb7e1b946c625a044965c5f4d7 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Wed, 18 Dec 2024 13:00:31 +0100 Subject: [PATCH 05/21] merge subseting sections of `[` and `get_code` --- R/qenv-constructor.R | 11 ++++++++--- R/qenv-eval_code.R | 3 ++- R/qenv-extract.R | 5 +++-- R/qenv-get_code.R | 5 +++-- man/qenv.Rd | 23 ++++++++++++++--------- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/R/qenv-constructor.R b/R/qenv-constructor.R index 0e1b5712..f7104eb2 100644 --- a/R/qenv-constructor.R +++ b/R/qenv-constructor.R @@ -18,11 +18,16 @@ #' A `qenv` inherits from the `environment` class, behaves like an environment, and has the #' following characteristics: #' -#' - The environment is locked, and data modification is only possible through the `eval_code()` +#' - `qenv` environment is locked, and data modification is only possible through the `eval_code()` #' and `within()` functions. #' - It stores metadata about the code used to create the data. -#' - Is immutable which means that each code evaluation does not modify the original `qenv` object -#' directly. +#' - Is immutable which means that each code evaluation does not modify the original `qenv` +#' environment directly. See the following code: +#' ``` +#' q1 <- qenv() +#' q2 <- eval_code(q1, "a <- 1") +#' identical(q1, q2) # FALSE +#' ``` #' #' @name qenv #' diff --git a/R/qenv-eval_code.R b/R/qenv-eval_code.R index 9be04dd8..8ba79130 100644 --- a/R/qenv-eval_code.R +++ b/R/qenv-eval_code.R @@ -1,6 +1,7 @@ #' Evaluate code in `qenv` #' #' @details +#' #' `eval_code()` evaluates given code in the `qenv` environment and appends it to the `code` slot. #' Thus, if the `qenv` had been instantiated empty, contents of the environment are always a result of the stored code. #' The `qenv` object is immutable, even though it inherits from the environment class, which is typically mutable by @@ -14,7 +15,7 @@ #' `expression` being a result of `parse(keep.source = TRUE)`. #' #' @return -#' `eval_code` returns a `qenv` object with `expr` evaluated or `qenv.error` if evaluation fails. +#' `eval_code` and `within` returns a `qenv` object with `expr` evaluated or `qenv.error` if evaluation fails. #' #' @examples #' # evaluate code in qenv diff --git a/R/qenv-extract.R b/R/qenv-extract.R index 0af75232..b5ab43c6 100644 --- a/R/qenv-extract.R +++ b/R/qenv-extract.R @@ -1,6 +1,7 @@ #' -#' @section Subsetting: -#' `x[names]` subsets objects in `qenv` environment and limit the code to the necessary needed to build limited objects. +#' @section Subsetting by the `names`: +#' +#' `x[names]` subsets `qenv` environment and limits the code to the necessary needed to build limited objects. #' `...` passes parameters to further methods. #' #' @param x (`qenv`) diff --git a/R/qenv-get_code.R b/R/qenv-get_code.R index 1c076c33..7f84446e 100644 --- a/R/qenv-get_code.R +++ b/R/qenv-get_code.R @@ -32,8 +32,9 @@ NULL #' @param ... see `Details` #' #' -#' @section Extracting dataset-specific code: -#' When `names` for `get_code` is specified, the code returned will be limited to the lines needed to _create_ +#' @section Subsetting by the `names`: +#' +#' `get_code(x, names)` limits the returned code to contain only those lines needed to _create_ #' the requested objects. The code stored in the `qenv` is analyzed statically to determine #' which lines the objects of interest depend upon. The analysis works well when objects are created #' with standard infix assignment operators (see `?assignOps`) but it can fail in some situations. diff --git a/man/qenv.Rd b/man/qenv.Rd index 00ba2df4..62eb7653 100644 --- a/man/qenv.Rd +++ b/man/qenv.Rd @@ -50,7 +50,7 @@ For more details see the "Extracting dataset-specific code" section.} \value{ \code{qenv} returns a \code{qenv} object. -\code{eval_code} returns a \code{qenv} object with \code{expr} evaluated or \code{qenv.error} if evaluation fails. +\code{eval_code} and \code{within} returns a \code{qenv} object with \code{expr} evaluated or \code{qenv.error} if evaluation fails. \code{[[}, \code{$} and \code{get} return the value of the object named \code{name} in the \code{qenv} object. @@ -97,23 +97,28 @@ as \code{name:value} pairs are passed to \code{...}, \code{name} in \code{expr} A \code{qenv} inherits from the \code{environment} class, behaves like an environment, and has the following characteristics: \itemize{ -\item The environment is locked, and data modification is only possible through the \code{eval_code()} +\item \code{qenv} environment is locked, and data modification is only possible through the \code{eval_code()} and \code{within()} functions. \item It stores metadata about the code used to create the data. -\item Is immutable which means that each code evaluation does not modify the original \code{qenv} object -directly. +\item Is immutable which means that each code evaluation does not modify the original \code{qenv} +environment directly. See the following code: + +\if{html}{\out{
}}\preformatted{q1 <- qenv() +q2 <- eval_code(q1, "a <- 1") +identical(q1, q2) # FALSE +}\if{html}{\out{
}} } } -\section{Subsetting}{ +\section{Subsetting by the \code{names}}{ + -\code{x[names]} subsets objects in \code{qenv} environment and limit the code to the necessary needed to build limited objects. +\code{x[names]} subsets \code{qenv} environment and limits the code to the necessary needed to build limited objects. \code{...} passes parameters to further methods. -} -\section{Extracting dataset-specific code}{ -When \code{names} for \code{get_code} is specified, the code returned will be limited to the lines needed to \emph{create} + +\code{get_code(x, names)} limits the returned code to contain only those lines needed to \emph{create} the requested objects. The code stored in the \code{qenv} is analyzed statically to determine which lines the objects of interest depend upon. The analysis works well when objects are created with standard infix assignment operators (see \code{?assignOps}) but it can fail in some situations. From 418d24851621376dde58944b1b4a8a9be6bb0dcd Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Wed, 18 Dec 2024 22:20:42 +0100 Subject: [PATCH 06/21] improve docs format --- R/qenv-constructor.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/qenv-constructor.R b/R/qenv-constructor.R index f7104eb2..f7da6a34 100644 --- a/R/qenv-constructor.R +++ b/R/qenv-constructor.R @@ -19,10 +19,11 @@ #' following characteristics: #' #' - `qenv` environment is locked, and data modification is only possible through the `eval_code()` -#' and `within()` functions. +#' and `within()` functions. #' - It stores metadata about the code used to create the data. #' - Is immutable which means that each code evaluation does not modify the original `qenv` -#' environment directly. See the following code: +#' environment directly. See the following code: +#' #' ``` #' q1 <- qenv() #' q2 <- eval_code(q1, "a <- 1") From 97f596863e8f9302a6cce38ba994944cecb29487 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 19 Dec 2024 00:25:27 +0100 Subject: [PATCH 07/21] split qenv methods to separate pages and link in qenv() docs --- R/qenv-constructor.R | 35 +++--- R/qenv-eval_code.R | 8 +- R/qenv-extract.R | 14 ++- R/qenv-get_code.R | 41 ++----- R/qenv-get_var.R | 7 +- R/qenv-within.R | 17 ++- man/eval_code.Rd | 88 +++++++++++++++ man/get_code.Rd | 113 +++++++++++++++++++ man/get_var.Rd | 5 +- man/qenv.Rd | 252 +++---------------------------------------- man/sub-.qenv.Rd | 26 +++++ 11 files changed, 282 insertions(+), 324 deletions(-) create mode 100644 man/eval_code.Rd create mode 100644 man/get_code.Rd create mode 100644 man/sub-.qenv.Rd diff --git a/R/qenv-constructor.R b/R/qenv-constructor.R index f7da6a34..ab25b75c 100644 --- a/R/qenv-constructor.R +++ b/R/qenv-constructor.R @@ -1,26 +1,18 @@ -#' Code tracking with `qenv` object +#' Instantiates a `qenv` environment #' #' @description #' `r badge("stable")` #' -#' Create a `qenv` object and evaluate code in it to track code history. -#' -#' @param names (`character`) for `x[names]`, names of objects included in `qenv` to subset. Names not present in `qenv` -#' are skipped. For `get_code` `r lifecycle::badge("experimental")` vector of object names to return the code for. -#' For more details see the "Extracting dataset-specific code" section. +#' Instantiates a `qenv` environment. #' #' @details +#' `qenv` class has following characteristics: #' -#' `qenv()` instantiates a with an empty `qenv` environment. -#' -#' @section `qenv` characteristics: -#' -#' A `qenv` inherits from the `environment` class, behaves like an environment, and has the -#' following characteristics: -#' -#' - `qenv` environment is locked, and data modification is only possible through the `eval_code()` -#' and `within()` functions. -#' - It stores metadata about the code used to create the data. +#' - It inherits from the environment and methods such as [`$`], [get()], [ls()], [as.list()], +#' [parent.env()] work out of the box. +#' - `qenv` is a locked environment, and data modification is only possible through the [eval_code()] +#' and [within.qenv()] functions. +#' - It stores metadata about the code used to create the data (see [get_code()]). #' - Is immutable which means that each code evaluation does not modify the original `qenv` #' environment directly. See the following code: #' @@ -32,13 +24,14 @@ #' #' @name qenv #' -#' @return `qenv` returns a `qenv` object. +#' @return `qenv` environment. #' -#' @seealso [`base::within()`], [`get_var()`], [`get_env()`], [`get_warnings()`], [`join()`], [`concat()`] +#' @seealso [eval_code()], [get_var()], [get_env()],[get_warnings()], [join()], [concat()] #' @examples -#' # create empty qenv -#' qenv() -#' +#' q <- qenv() +#' q2 <- within(q, a <- 1) +#' ls(q2) +#' q2$a #' @export qenv <- function() { methods::new("qenv") diff --git a/R/qenv-eval_code.R b/R/qenv-eval_code.R index 8ba79130..953c8cee 100644 --- a/R/qenv-eval_code.R +++ b/R/qenv-eval_code.R @@ -4,10 +4,6 @@ #' #' `eval_code()` evaluates given code in the `qenv` environment and appends it to the `code` slot. #' Thus, if the `qenv` had been instantiated empty, contents of the environment are always a result of the stored code. -#' The `qenv` object is immutable, even though it inherits from the environment class, which is typically mutable by -#' design. This means that each code evaluation does not modify the original `qenv` object directly. Instead, every -#' code evaluation creates a new `qenv` object that reflects the result of the changes, leaving the original object -#' unchanged. #' #' @param object (`qenv`) #' @param code (`character`, `language` or `expression`) code to evaluate. @@ -15,7 +11,7 @@ #' `expression` being a result of `parse(keep.source = TRUE)`. #' #' @return -#' `eval_code` and `within` returns a `qenv` object with `expr` evaluated or `qenv.error` if evaluation fails. +#' Returns a `qenv` object with `code/expr` evaluated or `qenv.error` if evaluation fails. #' #' @examples #' # evaluate code in qenv @@ -25,8 +21,6 @@ #' q <- eval_code(q, quote(library(checkmate))) #' q <- eval_code(q, expression(assert_number(a))) #' -#' @name eval_code -#' @rdname qenv #' @aliases eval_code,qenv,character-method #' @aliases eval_code,qenv,language-method #' @aliases eval_code,qenv,expression-method diff --git a/R/qenv-extract.R b/R/qenv-extract.R index b5ab43c6..97e98b41 100644 --- a/R/qenv-extract.R +++ b/R/qenv-extract.R @@ -1,21 +1,19 @@ +#' Subset `qenv` #' -#' @section Subsetting by the `names`: -#' -#' `x[names]` subsets `qenv` environment and limits the code to the necessary needed to build limited objects. -#' `...` passes parameters to further methods. +#' @description +#' Subsets [`qenv`] environment and limits the code to the necessary needed to build limited objects. #' #' @param x (`qenv`) +#' @param names (`character`) names of objects included in [`qenv`] to subset. Names not present in [`qenv`] +#' are skipped. +#' @param ... internal usage, please ignore. #' #' @examples -#' -#' # Subsetting #' q <- qenv() #' q <- eval_code(q, "a <- 1;b<-2") #' q["a"] #' q[c("a", "b")] #' -#' @rdname qenv -#' #' @export `[.qenv` <- function(x, names, ...) { checkmate::assert_character(names, any.missing = FALSE) diff --git a/R/qenv-get_code.R b/R/qenv-get_code.R index 7f84446e..3e5722a2 100644 --- a/R/qenv-get_code.R +++ b/R/qenv-get_code.R @@ -1,40 +1,17 @@ -#' @name qenv-inheritted -#' @rdname qenv -#' -#' @details -#' -#' `x[[name]]`, `x$name` and `get(name, x)` are generic \R operators to access the objects in the environment. -#' See [`[[`] for more details. -#' `names(x)` calls on the `qenv` object and will list all objects in the environment. -#' -#' @return `[[`, `$` and `get` return the value of the object named `name` in the `qenv` object. -#' @return `names` return a character vector of all the names of the objects in the `qenv` object. -#' @return `ls` return a character vector of the names of the objects in the `qenv` object. -#' It will only show the objects that are not named with a dot prefix, unless -#' the `all.names = TRUE`, which will show all objects. -#' -#' @examples -#' # Extract objects from qenv -#' q[["a"]] -#' q$a -#' -#' # list objects in qenv -#' names(q) -NULL - #' Get code from `qenv` #' -#' @details -#' `get_code()` retrieves the code stored in the `qenv`. `...` passes arguments to methods. +#' @description +#' Retrieves the code stored in the `qenv`. #' #' @param object (`qenv`) #' @param deparse (`logical(1)`) flag specifying whether to return code as `character` or `expression`. -#' @param ... see `Details` -#' +#' @param ... internal usage, please ignore. +#' @param names (`character`) `r lifecycle::badge("experimental")` vector of object names to return the code for. +#' For more details see the "Extracting dataset-specific code" section. #' -#' @section Subsetting by the `names`: +#' @section Extracting dataset-specific code: #' -#' `get_code(x, names)` limits the returned code to contain only those lines needed to _create_ +#' `get_code(object, names)` limits the returned code to contain only those lines needed to _create_ #' the requested objects. The code stored in the `qenv` is analyzed statically to determine #' which lines the objects of interest depend upon. The analysis works well when objects are created #' with standard infix assignment operators (see `?assignOps`) but it can fail in some situations. @@ -99,7 +76,7 @@ NULL #' - creating and evaluating language objects, _e.g._ `eval()` #' #' @return -#' `get_code` returns the traced code in the form specified by `deparse`. +#' Returns the traced code in the form specified by `deparse`. #' #' @examples #' # retrieve code @@ -115,8 +92,6 @@ NULL #' q <- eval_code(q, code = c("a <- 1", "b <- 2")) #' get_code(q, names = "a") #' -#' @name get_code -#' @rdname qenv #' @aliases get_code,qenv-method #' @aliases get_code,qenv.error-method #' diff --git a/R/qenv-get_var.R b/R/qenv-get_var.R index b370de4b..e80b4cc8 100644 --- a/R/qenv-get_var.R +++ b/R/qenv-get_var.R @@ -1,8 +1,9 @@ #' Get object from `qenv` #' #' @description -#' `r lifecycle::badge("deprecated")` by native \R operators/functions: -#' `x[[name]]`, `x$name` or [get()]. +#' `r lifecycle::badge("deprecated")` +#' Instead of [get_var()] use native \R operators/functions: +#' `x[[name]]`, `x$name` or [get()]: #' #' Retrieve variables from the `qenv` environment. #' @@ -17,8 +18,6 @@ #' q2 <- eval_code(q1, code = "b <- a") #' get_var(q2, "b") #' -#' @name get_var -#' @rdname get_var #' @aliases get_var,qenv,character-method #' @aliases get_var,qenv.error,ANY-method #' diff --git a/R/qenv-within.R b/R/qenv-within.R index 7d5fd32d..b4250063 100644 --- a/R/qenv-within.R +++ b/R/qenv-within.R @@ -1,11 +1,7 @@ -#' Evaluate Expression in `qenv` -#' #' @details -#' `within()` is a convenience function for evaluating inline code inside the environment of a `qenv`. -#' It is a method for the `base` generic that wraps `eval_code` to provide a simplified way of passing code. -#' `within` accepts only inline expressions (both simple and compound) and allows for injecting values into `expr` -#' through the `...` argument: -#' as `name:value` pairs are passed to `...`, `name` in `expr` will be replaced with `value`. +#' `within()` is a convenience method that wraps `eval_code` to provide a simplified way of passing expression. +#' `within` accepts only inline expressions (both simple and compound) and allows to substitute `expr` +#' with the `...` argument values. #' #' @section Using language objects with `within`: #' Passing language objects to `expr` is generally not intended but can be achieved with `do.call`. @@ -13,10 +9,9 @@ #' #' @param data (`qenv`) #' @param expr (`expression`) to evaluate. Must be inline code, see `Using language objects...` -#' @param ... see `Details` +#' @param ... (`named`) argument value will substitute a symbol in the `expr` matched by the name. +#' For practical examples see the #usage. #' -#' @return -#' `within` returns a `qenv` object with `expr` evaluated or `qenv.error` if evaluation fails. #' #' @examples #' # evaluate code using within @@ -49,7 +44,7 @@ #' within(q, exprlist) # fails #' do.call(within, list(q, do.call(c, exprlist))) #' -#' @rdname qenv +#' @rdname eval_code #' #' @export #' diff --git a/man/eval_code.Rd b/man/eval_code.Rd new file mode 100644 index 00000000..a63e3c7f --- /dev/null +++ b/man/eval_code.Rd @@ -0,0 +1,88 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/qenv-eval_code.R, R/qenv-within.R +\name{eval_code} +\alias{eval_code} +\alias{eval_code,qenv,character-method} +\alias{eval_code,qenv,language-method} +\alias{eval_code,qenv,expression-method} +\alias{eval_code,qenv.error,ANY-method} +\alias{within.qenv} +\title{Evaluate code in \code{qenv}} +\usage{ +eval_code(object, code) + +\method{within}{qenv}(data, expr, ...) +} +\arguments{ +\item{object}{(\code{qenv})} + +\item{code}{(\code{character}, \code{language} or \code{expression}) code to evaluate. +It is possible to preserve original formatting of the \code{code} by providing a \code{character} or an +\code{expression} being a result of \code{parse(keep.source = TRUE)}.} + +\item{data}{(\code{qenv})} + +\item{expr}{(\code{expression}) to evaluate. Must be inline code, see \verb{Using language objects...}} + +\item{...}{(\code{named}) argument value will substitute a symbol in the \code{expr} matched by the name. +For practical examples see the #usage.} +} +\value{ +Returns a \code{qenv} object with \code{code/expr} evaluated or \code{qenv.error} if evaluation fails. +} +\description{ +Evaluate code in \code{qenv} +} +\details{ +\code{eval_code()} evaluates given code in the \code{qenv} environment and appends it to the \code{code} slot. +Thus, if the \code{qenv} had been instantiated empty, contents of the environment are always a result of the stored code. + +\code{within()} is a convenience method that wraps \code{eval_code} to provide a simplified way of passing expression. +\code{within} accepts only inline expressions (both simple and compound) and allows to substitute \code{expr} +with the \code{...} argument values. +} +\section{Using language objects with \code{within}}{ + +Passing language objects to \code{expr} is generally not intended but can be achieved with \code{do.call}. +Only single \code{expression}s will work and substitution is not available. See examples. +} + +\examples{ +# evaluate code in qenv +q <- qenv() +q <- eval_code(q, "a <- 1") +q <- eval_code(q, "b <- 2L # with comment") +q <- eval_code(q, quote(library(checkmate))) +q <- eval_code(q, expression(assert_number(a))) + +# evaluate code using within +q <- qenv() +q <- within(q, { + i <- iris +}) +q <- within(q, { + m <- mtcars + f <- faithful +}) +q +get_code(q) + +# inject values into code +q <- qenv() +q <- within(q, i <- iris) +within(q, print(dim(subset(i, Species == "virginica")))) +within(q, print(dim(subset(i, Species == species)))) # fails +within(q, print(dim(subset(i, Species == species))), species = "versicolor") +species_external <- "versicolor" +within(q, print(dim(subset(i, Species == species))), species = species_external) + +# pass language objects +expr <- expression(i <- iris, m <- mtcars) +within(q, expr) # fails +do.call(within, list(q, expr)) + +exprlist <- list(expression(i <- iris), expression(m <- mtcars)) +within(q, exprlist) # fails +do.call(within, list(q, do.call(c, exprlist))) + +} diff --git a/man/get_code.Rd b/man/get_code.Rd new file mode 100644 index 00000000..a2baddac --- /dev/null +++ b/man/get_code.Rd @@ -0,0 +1,113 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/qenv-get_code.R +\name{get_code} +\alias{get_code} +\alias{get_code,qenv-method} +\alias{get_code,qenv.error-method} +\title{Get code from \code{qenv}} +\usage{ +get_code(object, deparse = TRUE, names = NULL, ...) +} +\arguments{ +\item{object}{(\code{qenv})} + +\item{deparse}{(\code{logical(1)}) flag specifying whether to return code as \code{character} or \code{expression}.} + +\item{names}{(\code{character}) \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} vector of object names to return the code for. +For more details see the "Extracting dataset-specific code" section.} + +\item{...}{internal usage, please ignore.} +} +\value{ +Returns the traced code in the form specified by \code{deparse}. +} +\description{ +Retrieves the code stored in the \code{qenv}. +} +\section{Extracting dataset-specific code}{ + + +\code{get_code(object, names)} limits the returned code to contain only those lines needed to \emph{create} +the requested objects. The code stored in the \code{qenv} is analyzed statically to determine +which lines the objects of interest depend upon. The analysis works well when objects are created +with standard infix assignment operators (see \code{?assignOps}) but it can fail in some situations. + +Consider the following examples: + +\emph{Case 1: Usual assignments.} + +\if{html}{\out{
}}\preformatted{q1 <- + within(qenv(), \{ + foo <- function(x) \{ + x + 1 + \} + x <- 0 + y <- foo(x) + \}) +get_code(q1, names = "y") +}\if{html}{\out{
}} + +\code{x} has no dependencies, so \code{get_code(data, names = "x")} will return only the second call.\cr +\code{y} depends on \code{x} and \code{foo}, so \code{get_code(data, names = "y")} will contain all three calls. + +\emph{Case 2: Some objects are created by a function's side effects.} + +\if{html}{\out{
}}\preformatted{q2 <- + within(qenv()\{ + foo <- function() \{ + x <<- x + 1 + \} + x <- 0 + foo() + y <- x + \}) +get_code(q2, names = "y") +}\if{html}{\out{
}} + +Here, \code{y} depends on \code{x} but \code{x} is modified by \code{foo} as a side effect (not by reassignment) +and so \code{get_code(data, names = "y")} will not return the \code{foo()} call.\cr +To overcome this limitation, code dependencies can be specified manually. +Lines where side effects occur can be flagged by adding "\verb{# @linksto }" at the end.\cr +Note that \code{within} evaluates code passed to \code{expr} as is and comments are ignored. +In order to include comments in code one must use the \code{eval_code} function instead. + +\if{html}{\out{
}}\preformatted{q3 <- + eval_code(qenv(), " + foo <- function() \{ + x <<- x + 1 + \} + x <- 0 + foo() # @linksto x + y <- x + ") +get_code(q3, names = "y") +}\if{html}{\out{
}} + +Now the \code{foo()} call will be properly included in the code required to recreate \code{y}. + +Note that two functions that create objects as side effects, \code{assign} and \code{data}, are handled automatically. + +Here are known cases where manual tagging is necessary: +\itemize{ +\item non-standard assignment operators, \emph{e.g.} \verb{\%<>\%} +\item objects used as conditions in \code{if} statements: \verb{if ()} +\item objects used to iterate over in \code{for} loops: \verb{for(i in )} +\item creating and evaluating language objects, \emph{e.g.} \verb{eval()} +} +} + +\examples{ +# retrieve code +q <- within(qenv(), { + a <- 1 + b <- 2 +}) +get_code(q) +get_code(q, deparse = FALSE) +get_code(q, names = "a") + +q <- qenv() +q <- eval_code(q, code = c("a <- 1", "b <- 2")) +get_code(q, names = "a") + +} diff --git a/man/get_var.Rd b/man/get_var.Rd index 7b40bbaa..ff8b7120 100644 --- a/man/get_var.Rd +++ b/man/get_var.Rd @@ -20,8 +20,9 @@ get_var(object, var) The value of required variable (\code{var}) within \code{qenv} object. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} by native \R operators/functions: -\code{x[[name]]}, \code{x$name} or \code{\link[=get]{get()}}. +\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. } diff --git a/man/qenv.Rd b/man/qenv.Rd index 62eb7653..bf3636db 100644 --- a/man/qenv.Rd +++ b/man/qenv.Rd @@ -1,105 +1,27 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/qenv-constructor.R, R/qenv-eval_code.R, -% R/qenv-extract.R, R/qenv-get_code.R, R/qenv-within.R +% Please edit documentation in R/qenv-constructor.R \name{qenv} \alias{qenv} -\alias{eval_code} -\alias{eval_code,qenv,character-method} -\alias{eval_code,qenv,language-method} -\alias{eval_code,qenv,expression-method} -\alias{eval_code,qenv.error,ANY-method} -\alias{[.qenv} -\alias{qenv-inheritted} -\alias{get_code} -\alias{get_code,qenv-method} -\alias{get_code,qenv.error-method} -\alias{within.qenv} -\title{Code tracking with \code{qenv} object} +\title{Instantiates a \code{qenv} environment} \usage{ qenv() - -eval_code(object, code) - -\method{[}{qenv}(x, names, ...) - -get_code(object, deparse = TRUE, names = NULL, ...) - -\method{within}{qenv}(data, expr, ...) -} -\arguments{ -\item{object}{(\code{qenv})} - -\item{code}{(\code{character}, \code{language} or \code{expression}) code to evaluate. -It is possible to preserve original formatting of the \code{code} by providing a \code{character} or an -\code{expression} being a result of \code{parse(keep.source = TRUE)}.} - -\item{x}{(\code{qenv})} - -\item{names}{(\code{character}) for \code{x[names]}, names of objects included in \code{qenv} to subset. Names not present in \code{qenv} -are skipped. For \code{get_code} \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} vector of object names to return the code for. -For more details see the "Extracting dataset-specific code" section.} - -\item{...}{see \code{Details}} - -\item{deparse}{(\code{logical(1)}) flag specifying whether to return code as \code{character} or \code{expression}.} - -\item{data}{(\code{qenv})} - -\item{expr}{(\code{expression}) to evaluate. Must be inline code, see \verb{Using language objects...}} } \value{ -\code{qenv} returns a \code{qenv} object. - -\code{eval_code} and \code{within} returns a \code{qenv} object with \code{expr} evaluated or \code{qenv.error} if evaluation fails. - -\code{[[}, \code{$} and \code{get} return the value of the object named \code{name} in the \code{qenv} object. - -\code{names} return a character vector of all the names of the objects in the \code{qenv} object. - -\code{ls} return a character vector of the names of the objects in the \code{qenv} object. -It will only show the objects that are not named with a dot prefix, unless -the \code{all.names = TRUE}, which will show all objects. - -\code{get_code} returns the traced code in the form specified by \code{deparse}. - -\code{within} returns a \code{qenv} object with \code{expr} evaluated or \code{qenv.error} if evaluation fails. +\code{qenv} environment. } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} -Create a \code{qenv} object and evaluate code in it to track code history. +Instantiates a \code{qenv} environment. } \details{ -\code{qenv()} instantiates a with an empty \code{qenv} environment. - -\code{eval_code()} evaluates given code in the \code{qenv} environment and appends it to the \code{code} slot. -Thus, if the \code{qenv} had been instantiated empty, contents of the environment are always a result of the stored code. -The \code{qenv} object is immutable, even though it inherits from the environment class, which is typically mutable by -design. This means that each code evaluation does not modify the original \code{qenv} object directly. Instead, every -code evaluation creates a new \code{qenv} object that reflects the result of the changes, leaving the original object -unchanged. - -\code{x[[name]]}, \code{x$name} and \code{get(name, x)} are generic \R operators to access the objects in the environment. -See [\code{[[}] for more details. -\code{names(x)} calls on the \code{qenv} object and will list all objects in the environment. - -\code{get_code()} retrieves the code stored in the \code{qenv}. \code{...} passes arguments to methods. - -\code{within()} is a convenience function for evaluating inline code inside the environment of a \code{qenv}. -It is a method for the \code{base} generic that wraps \code{eval_code} to provide a simplified way of passing code. -\code{within} accepts only inline expressions (both simple and compound) and allows for injecting values into \code{expr} -through the \code{...} argument: -as \code{name:value} pairs are passed to \code{...}, \code{name} in \code{expr} will be replaced with \code{value}. -} -\section{\code{qenv} characteristics}{ - - -A \code{qenv} inherits from the \code{environment} class, behaves like an environment, and has the -following characteristics: +\code{qenv} class has following characteristics: \itemize{ -\item \code{qenv} environment is locked, and data modification is only possible through the \code{eval_code()} -and \code{within()} functions. -\item It stores metadata about the code used to create the data. +\item It inherits from the environment and methods such as \code{\link{$}}, \code{\link[=get]{get()}}, \code{\link[=ls]{ls()}}, \code{\link[=as.list]{as.list()}}, +\code{\link[=parent.env]{parent.env()}} work out of the box. +\item \code{qenv} is a locked environment, and data modification is only possible through the \code{\link[=eval_code]{eval_code()}} +and \code{\link[=within.qenv]{within.qenv()}} functions. +\item It stores metadata about the code used to create the data (see \code{\link[=get_code]{get_code()}}). \item Is immutable which means that each code evaluation does not modify the original \code{qenv} environment directly. See the following code: @@ -109,158 +31,12 @@ identical(q1, q2) # FALSE }\if{html}{\out{}} } } - -\section{Subsetting by the \code{names}}{ - - -\code{x[names]} subsets \code{qenv} environment and limits the code to the necessary needed to build limited objects. -\code{...} passes parameters to further methods. - - - -\code{get_code(x, names)} limits the returned code to contain only those lines needed to \emph{create} -the requested objects. The code stored in the \code{qenv} is analyzed statically to determine -which lines the objects of interest depend upon. The analysis works well when objects are created -with standard infix assignment operators (see \code{?assignOps}) but it can fail in some situations. - -Consider the following examples: - -\emph{Case 1: Usual assignments.} - -\if{html}{\out{
}}\preformatted{q1 <- - within(qenv(), \{ - foo <- function(x) \{ - x + 1 - \} - x <- 0 - y <- foo(x) - \}) -get_code(q1, names = "y") -}\if{html}{\out{
}} - -\code{x} has no dependencies, so \code{get_code(data, names = "x")} will return only the second call.\cr -\code{y} depends on \code{x} and \code{foo}, so \code{get_code(data, names = "y")} will contain all three calls. - -\emph{Case 2: Some objects are created by a function's side effects.} - -\if{html}{\out{
}}\preformatted{q2 <- - within(qenv()\{ - foo <- function() \{ - x <<- x + 1 - \} - x <- 0 - foo() - y <- x - \}) -get_code(q2, names = "y") -}\if{html}{\out{
}} - -Here, \code{y} depends on \code{x} but \code{x} is modified by \code{foo} as a side effect (not by reassignment) -and so \code{get_code(data, names = "y")} will not return the \code{foo()} call.\cr -To overcome this limitation, code dependencies can be specified manually. -Lines where side effects occur can be flagged by adding "\verb{# @linksto }" at the end.\cr -Note that \code{within} evaluates code passed to \code{expr} as is and comments are ignored. -In order to include comments in code one must use the \code{eval_code} function instead. - -\if{html}{\out{
}}\preformatted{q3 <- - eval_code(qenv(), " - foo <- function() \{ - x <<- x + 1 - \} - x <- 0 - foo() # @linksto x - y <- x - ") -get_code(q3, names = "y") -}\if{html}{\out{
}} - -Now the \code{foo()} call will be properly included in the code required to recreate \code{y}. - -Note that two functions that create objects as side effects, \code{assign} and \code{data}, are handled automatically. - -Here are known cases where manual tagging is necessary: -\itemize{ -\item non-standard assignment operators, \emph{e.g.} \verb{\%<>\%} -\item objects used as conditions in \code{if} statements: \verb{if ()} -\item objects used to iterate over in \code{for} loops: \verb{for(i in )} -\item creating and evaluating language objects, \emph{e.g.} \verb{eval()} -} -} - -\section{Using language objects with \code{within}}{ - -Passing language objects to \code{expr} is generally not intended but can be achieved with \code{do.call}. -Only single \code{expression}s will work and substitution is not available. See examples. -} - \examples{ -# create empty qenv -qenv() - -# evaluate code in qenv q <- qenv() -q <- eval_code(q, "a <- 1") -q <- eval_code(q, "b <- 2L # with comment") -q <- eval_code(q, quote(library(checkmate))) -q <- eval_code(q, expression(assert_number(a))) - - -# Subsetting -q <- qenv() -q <- eval_code(q, "a <- 1;b<-2") -q["a"] -q[c("a", "b")] - -# Extract objects from qenv -q[["a"]] -q$a - -# list objects in qenv -names(q) -# retrieve code -q <- within(qenv(), { - a <- 1 - b <- 2 -}) -get_code(q) -get_code(q, deparse = FALSE) -get_code(q, names = "a") - -q <- qenv() -q <- eval_code(q, code = c("a <- 1", "b <- 2")) -get_code(q, names = "a") - -# evaluate code using within -q <- qenv() -q <- within(q, { - i <- iris -}) -q <- within(q, { - m <- mtcars - f <- faithful -}) -q -get_code(q) - -# inject values into code -q <- qenv() -q <- within(q, i <- iris) -within(q, print(dim(subset(i, Species == "virginica")))) -within(q, print(dim(subset(i, Species == species)))) # fails -within(q, print(dim(subset(i, Species == species))), species = "versicolor") -species_external <- "versicolor" -within(q, print(dim(subset(i, Species == species))), species = species_external) - -# pass language objects -expr <- expression(i <- iris, m <- mtcars) -within(q, expr) # fails -do.call(within, list(q, expr)) - -exprlist <- list(expression(i <- iris), expression(m <- mtcars)) -within(q, exprlist) # fails -do.call(within, list(q, do.call(c, exprlist))) - +q2 <- within(q, a <- 1) +ls(q2) +q2$a } \seealso{ -\code{\link[base:with]{base::within()}}, \code{\link[=get_var]{get_var()}}, \code{\link[=get_env]{get_env()}}, \code{\link[=get_warnings]{get_warnings()}}, \code{\link[=join]{join()}}, \code{\link[=concat]{concat()}} +\code{\link[=eval_code]{eval_code()}}, \code{\link[=get_var]{get_var()}}, \code{\link[=get_env]{get_env()}},\code{\link[=get_warnings]{get_warnings()}}, \code{\link[=join]{join()}}, \code{\link[=concat]{concat()}} } diff --git a/man/sub-.qenv.Rd b/man/sub-.qenv.Rd new file mode 100644 index 00000000..02fe8291 --- /dev/null +++ b/man/sub-.qenv.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/qenv-extract.R +\name{[.qenv} +\alias{[.qenv} +\title{Subset \code{qenv}} +\usage{ +\method{[}{qenv}(x, names, ...) +} +\arguments{ +\item{x}{(\code{qenv})} + +\item{names}{(\code{character}) names of objects included in \code{\link{qenv}} to subset. Names not present in \code{\link{qenv}} +are skipped.} + +\item{...}{internal usage, please ignore.} +} +\description{ +Subsets \code{\link{qenv}} environment and limits the code to the necessary needed to build limited objects. +} +\examples{ +q <- qenv() +q <- eval_code(q, "a <- 1;b<-2") +q["a"] +q[c("a", "b")] + +} From ecb32419249d7911d6e85f586479abf075d55015 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 19 Dec 2024 08:20:02 +0100 Subject: [PATCH 08/21] link extract-qenv in roxy and pkgdown --- R/qenv-constructor.R | 2 +- R/qenv-extract.R | 2 ++ _pkgdown.yml | 1 + man/{sub-.qenv.Rd => extract-qenv.Rd} | 3 ++- man/qenv.Rd | 2 +- 5 files changed, 7 insertions(+), 3 deletions(-) rename man/{sub-.qenv.Rd => extract-qenv.Rd} (93%) diff --git a/R/qenv-constructor.R b/R/qenv-constructor.R index ab25b75c..539a9629 100644 --- a/R/qenv-constructor.R +++ b/R/qenv-constructor.R @@ -26,7 +26,7 @@ #' #' @return `qenv` environment. #' -#' @seealso [eval_code()], [get_var()], [get_env()],[get_warnings()], [join()], [concat()] +#' @seealso [eval_code()], [get_var()], [`extract-qenv`], [get_env()],[get_warnings()], [join()], [concat()] #' @examples #' q <- qenv() #' q2 <- within(q, a <- 1) diff --git a/R/qenv-extract.R b/R/qenv-extract.R index 97e98b41..2f2385d1 100644 --- a/R/qenv-extract.R +++ b/R/qenv-extract.R @@ -8,6 +8,8 @@ #' are skipped. #' @param ... internal usage, please ignore. #' +#' @name extract-qenv +#' #' @examples #' q <- qenv() #' q <- eval_code(q, "a <- 1;b<-2") diff --git a/_pkgdown.yml b/_pkgdown.yml index 7837af58..64d330f6 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -26,6 +26,7 @@ reference: - title: "Reproducible qenv objects" desc: "methods to get and modify values of qenv objects" contents: + - extract-qenv - concat - dev_suppress - eval_code diff --git a/man/sub-.qenv.Rd b/man/extract-qenv.Rd similarity index 93% rename from man/sub-.qenv.Rd rename to man/extract-qenv.Rd index 02fe8291..9ecf1037 100644 --- a/man/sub-.qenv.Rd +++ b/man/extract-qenv.Rd @@ -1,6 +1,7 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/qenv-extract.R -\name{[.qenv} +\name{extract-qenv} +\alias{extract-qenv} \alias{[.qenv} \title{Subset \code{qenv}} \usage{ diff --git a/man/qenv.Rd b/man/qenv.Rd index bf3636db..96dc7176 100644 --- a/man/qenv.Rd +++ b/man/qenv.Rd @@ -38,5 +38,5 @@ ls(q2) q2$a } \seealso{ -\code{\link[=eval_code]{eval_code()}}, \code{\link[=get_var]{get_var()}}, \code{\link[=get_env]{get_env()}},\code{\link[=get_warnings]{get_warnings()}}, \code{\link[=join]{join()}}, \code{\link[=concat]{concat()}} +\code{\link[=eval_code]{eval_code()}}, \code{\link[=get_var]{get_var()}}, \code{\link{extract-qenv}}, \code{\link[=get_env]{get_env()}},\code{\link[=get_warnings]{get_warnings()}}, \code{\link[=join]{join()}}, \code{\link[=concat]{concat()}} } From 3ec91a184e630d6239d9a98223e1322c1b37ad02 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 19 Dec 2024 10:05:49 +0100 Subject: [PATCH 09/21] add slicing characteristic adjust vignette to qenv details --- R/qenv-constructor.R | 1 + R/qenv-extract.R | 4 ++-- _pkgdown.yml | 2 +- man/qenv.Rd | 1 + man/{extract-qenv.Rd => subset-qenv.Rd} | 6 +++--- vignettes/qenv.Rmd | 8 +++++--- 6 files changed, 13 insertions(+), 9 deletions(-) rename man/{extract-qenv.Rd => subset-qenv.Rd} (89%) diff --git a/R/qenv-constructor.R b/R/qenv-constructor.R index 539a9629..8a1b3ffe 100644 --- a/R/qenv-constructor.R +++ b/R/qenv-constructor.R @@ -13,6 +13,7 @@ #' - `qenv` is a locked environment, and data modification is only possible through the [eval_code()] #' and [within.qenv()] functions. #' - It stores metadata about the code used to create the data (see [get_code()]). +#' - It supports slicing (see [`subset-qenv`]) #' - Is immutable which means that each code evaluation does not modify the original `qenv` #' environment directly. See the following code: #' diff --git a/R/qenv-extract.R b/R/qenv-extract.R index 2f2385d1..48c63d2a 100644 --- a/R/qenv-extract.R +++ b/R/qenv-extract.R @@ -1,4 +1,4 @@ -#' Subset `qenv` +#' Subsets `qenv` #' #' @description #' Subsets [`qenv`] environment and limits the code to the necessary needed to build limited objects. @@ -8,7 +8,7 @@ #' are skipped. #' @param ... internal usage, please ignore. #' -#' @name extract-qenv +#' @name subset-qenv #' #' @examples #' q <- qenv() diff --git a/_pkgdown.yml b/_pkgdown.yml index 64d330f6..e4a8c973 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -26,7 +26,6 @@ reference: - title: "Reproducible qenv objects" desc: "methods to get and modify values of qenv objects" contents: - - extract-qenv - concat - dev_suppress - eval_code @@ -38,4 +37,5 @@ reference: - join - qenv - show,qenv-method + - subset-qenv - within.qenv diff --git a/man/qenv.Rd b/man/qenv.Rd index 96dc7176..8bc07a99 100644 --- a/man/qenv.Rd +++ b/man/qenv.Rd @@ -22,6 +22,7 @@ Instantiates a \code{qenv} environment. \item \code{qenv} is a locked environment, and data modification is only possible through the \code{\link[=eval_code]{eval_code()}} and \code{\link[=within.qenv]{within.qenv()}} functions. \item It stores metadata about the code used to create the data (see \code{\link[=get_code]{get_code()}}). +\item It supports slicing (see \code{\link{subset-qenv}}) \item Is immutable which means that each code evaluation does not modify the original \code{qenv} environment directly. See the following code: diff --git a/man/extract-qenv.Rd b/man/subset-qenv.Rd similarity index 89% rename from man/extract-qenv.Rd rename to man/subset-qenv.Rd index 9ecf1037..8ae6b2ff 100644 --- a/man/extract-qenv.Rd +++ b/man/subset-qenv.Rd @@ -1,9 +1,9 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/qenv-extract.R -\name{extract-qenv} -\alias{extract-qenv} +\name{subset-qenv} +\alias{subset-qenv} \alias{[.qenv} -\title{Subset \code{qenv}} +\title{Subsets \code{qenv}} \usage{ \method{[}{qenv}(x, names, ...) } diff --git a/vignettes/qenv.Rmd b/vignettes/qenv.Rmd index e2493fb4..314a88ff 100644 --- a/vignettes/qenv.Rmd +++ b/vignettes/qenv.Rmd @@ -12,9 +12,11 @@ vignette: > A `qenv` inherits from the `environment` class, behaves like an environment, and has the following characteristics: -- The environment is locked, and data modification is only possible through the `eval_code()` and `within()` functions. -- It stores metadata about the code used to create the data. -- Is immutable which means that each code evaluation does not modify the original `qenv` object directly. +- It inherits from the environment and methods such as `$`, `get`, `ls`, `as.list()` work out of the box. +- `qenv` is a locked environment, and data modification is only possible through the `eval_code` and `within` functions. +- It stores metadata about the code used to create the data (see `get_code`). +- It supports slicing by `[`. +- Is immutable which means that each code evaluation does not modify the original `qenv` environment directly. ### Initialization From 98021e22d77eac30eccced8803ffd0e3bfea14bf Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 19 Dec 2024 10:14:58 +0100 Subject: [PATCH 10/21] small docs fix --- R/qenv-constructor.R | 2 +- man/qenv.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/qenv-constructor.R b/R/qenv-constructor.R index 8a1b3ffe..fb209f93 100644 --- a/R/qenv-constructor.R +++ b/R/qenv-constructor.R @@ -27,7 +27,7 @@ #' #' @return `qenv` environment. #' -#' @seealso [eval_code()], [get_var()], [`extract-qenv`], [get_env()],[get_warnings()], [join()], [concat()] +#' @seealso [eval_code()], [get_var()], [`subset-qenv`], [get_env()],[get_warnings()], [join()], [concat()] #' @examples #' q <- qenv() #' q2 <- within(q, a <- 1) diff --git a/man/qenv.Rd b/man/qenv.Rd index 8bc07a99..366d24c6 100644 --- a/man/qenv.Rd +++ b/man/qenv.Rd @@ -39,5 +39,5 @@ ls(q2) q2$a } \seealso{ -\code{\link[=eval_code]{eval_code()}}, \code{\link[=get_var]{get_var()}}, \code{\link{extract-qenv}}, \code{\link[=get_env]{get_env()}},\code{\link[=get_warnings]{get_warnings()}}, \code{\link[=join]{join()}}, \code{\link[=concat]{concat()}} +\code{\link[=eval_code]{eval_code()}}, \code{\link[=get_var]{get_var()}}, \code{\link{subset-qenv}}, \code{\link[=get_env]{get_env()}},\code{\link[=get_warnings]{get_warnings()}}, \code{\link[=join]{join()}}, \code{\link[=concat]{concat()}} } From 8be3e695a4cd2e80040a8cdd924fa16498acf4be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ka=C5=82=C4=99dkowski?= Date: Thu, 19 Dec 2024 15:16:02 +0100 Subject: [PATCH 11/21] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: André Veríssimo <211358+averissimo@users.noreply.github.com> Signed-off-by: Dawid Kałędkowski --- R/qenv-eval_code.R | 2 +- R/qenv-get_code.R | 2 +- R/qenv-within.R | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/R/qenv-eval_code.R b/R/qenv-eval_code.R index 953c8cee..b8593a33 100644 --- a/R/qenv-eval_code.R +++ b/R/qenv-eval_code.R @@ -11,7 +11,7 @@ #' `expression` being a result of `parse(keep.source = TRUE)`. #' #' @return -#' Returns a `qenv` object with `code/expr` evaluated or `qenv.error` if evaluation fails. +#' `qenv` environment with `code/expr` evaluated or `qenv.error` if evaluation fails. #' #' @examples #' # evaluate code in qenv diff --git a/R/qenv-get_code.R b/R/qenv-get_code.R index 3e5722a2..13609610 100644 --- a/R/qenv-get_code.R +++ b/R/qenv-get_code.R @@ -76,7 +76,7 @@ #' - creating and evaluating language objects, _e.g._ `eval()` #' #' @return -#' Returns the traced code in the form specified by `deparse`. +#' The code used in the `qenv` in the form specified by `deparse`. #' #' @examples #' # retrieve code diff --git a/R/qenv-within.R b/R/qenv-within.R index b4250063..d183c3b0 100644 --- a/R/qenv-within.R +++ b/R/qenv-within.R @@ -1,7 +1,7 @@ #' @details #' `within()` is a convenience method that wraps `eval_code` to provide a simplified way of passing expression. #' `within` accepts only inline expressions (both simple and compound) and allows to substitute `expr` -#' with the `...` argument values. +#' with `...` named argument values. #' #' @section Using language objects with `within`: #' Passing language objects to `expr` is generally not intended but can be achieved with `do.call`. @@ -9,8 +9,8 @@ #' #' @param data (`qenv`) #' @param expr (`expression`) to evaluate. Must be inline code, see `Using language objects...` -#' @param ... (`named`) argument value will substitute a symbol in the `expr` matched by the name. -#' For practical examples see the #usage. +#' @param ... named argument value will substitute a symbol in the `expr` matched by the name. +#' For practical examples see the [usage](#ref-usage) above. #' #' #' @examples From 373634efad2e8077ba15c31da5c9ec015309226c Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:19:06 +0000 Subject: [PATCH 12/21] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/eval_code.Rd | 8 ++++---- man/get_code.Rd | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/man/eval_code.Rd b/man/eval_code.Rd index a63e3c7f..8016884d 100644 --- a/man/eval_code.Rd +++ b/man/eval_code.Rd @@ -24,11 +24,11 @@ It is possible to preserve original formatting of the \code{code} by providing a \item{expr}{(\code{expression}) to evaluate. Must be inline code, see \verb{Using language objects...}} -\item{...}{(\code{named}) argument value will substitute a symbol in the \code{expr} matched by the name. -For practical examples see the #usage.} +\item{...}{named argument value will substitute a symbol in the \code{expr} matched by the name. +For practical examples see the \href{#ref-usage}{usage} above.} } \value{ -Returns a \code{qenv} object with \code{code/expr} evaluated or \code{qenv.error} if evaluation fails. +\code{qenv} environment with \code{code/expr} evaluated or \code{qenv.error} if evaluation fails. } \description{ Evaluate code in \code{qenv} @@ -39,7 +39,7 @@ Thus, if the \code{qenv} had been instantiated empty, contents of the environmen \code{within()} is a convenience method that wraps \code{eval_code} to provide a simplified way of passing expression. \code{within} accepts only inline expressions (both simple and compound) and allows to substitute \code{expr} -with the \code{...} argument values. +with \code{...} named argument values. } \section{Using language objects with \code{within}}{ diff --git a/man/get_code.Rd b/man/get_code.Rd index a2baddac..af8ca3c0 100644 --- a/man/get_code.Rd +++ b/man/get_code.Rd @@ -19,7 +19,7 @@ For more details see the "Extracting dataset-specific code" section.} \item{...}{internal usage, please ignore.} } \value{ -Returns the traced code in the form specified by \code{deparse}. +The code used in the \code{qenv} in the form specified by \code{deparse}. } \description{ Retrieves the code stored in the \code{qenv}. From 394edf129401ef54b0d4d43dfb5305db8cf1fdc1 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 19 Dec 2024 15:24:50 +0100 Subject: [PATCH 13/21] fixes --- R/qenv-constructor.R | 2 +- R/qenv-within.R | 3 +-- man/eval_code.Rd | 8 ++++---- man/get_code.Rd | 2 +- man/qenv.Rd | 2 +- vignettes/qenv.Rmd | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/R/qenv-constructor.R b/R/qenv-constructor.R index fb209f93..75d2757e 100644 --- a/R/qenv-constructor.R +++ b/R/qenv-constructor.R @@ -14,7 +14,7 @@ #' and [within.qenv()] functions. #' - It stores metadata about the code used to create the data (see [get_code()]). #' - It supports slicing (see [`subset-qenv`]) -#' - Is immutable which means that each code evaluation does not modify the original `qenv` +#' - It is immutable which means that each code evaluation does not modify the original `qenv` #' environment directly. See the following code: #' #' ``` diff --git a/R/qenv-within.R b/R/qenv-within.R index d183c3b0..ef68da14 100644 --- a/R/qenv-within.R +++ b/R/qenv-within.R @@ -10,8 +10,7 @@ #' @param data (`qenv`) #' @param expr (`expression`) to evaluate. Must be inline code, see `Using language objects...` #' @param ... named argument value will substitute a symbol in the `expr` matched by the name. -#' For practical examples see the [usage](#ref-usage) above. -#' +#' For practical usage see Examples section below. #' #' @examples #' # evaluate code using within diff --git a/man/eval_code.Rd b/man/eval_code.Rd index a63e3c7f..203a96af 100644 --- a/man/eval_code.Rd +++ b/man/eval_code.Rd @@ -24,11 +24,11 @@ It is possible to preserve original formatting of the \code{code} by providing a \item{expr}{(\code{expression}) to evaluate. Must be inline code, see \verb{Using language objects...}} -\item{...}{(\code{named}) argument value will substitute a symbol in the \code{expr} matched by the name. -For practical examples see the #usage.} +\item{...}{named argument value will substitute a symbol in the \code{expr} matched by the name. +For practical usage see Examples section below.} } \value{ -Returns a \code{qenv} object with \code{code/expr} evaluated or \code{qenv.error} if evaluation fails. +\code{qenv} environment with \code{code/expr} evaluated or \code{qenv.error} if evaluation fails. } \description{ Evaluate code in \code{qenv} @@ -39,7 +39,7 @@ Thus, if the \code{qenv} had been instantiated empty, contents of the environmen \code{within()} is a convenience method that wraps \code{eval_code} to provide a simplified way of passing expression. \code{within} accepts only inline expressions (both simple and compound) and allows to substitute \code{expr} -with the \code{...} argument values. +with \code{...} named argument values. } \section{Using language objects with \code{within}}{ diff --git a/man/get_code.Rd b/man/get_code.Rd index a2baddac..af8ca3c0 100644 --- a/man/get_code.Rd +++ b/man/get_code.Rd @@ -19,7 +19,7 @@ For more details see the "Extracting dataset-specific code" section.} \item{...}{internal usage, please ignore.} } \value{ -Returns the traced code in the form specified by \code{deparse}. +The code used in the \code{qenv} in the form specified by \code{deparse}. } \description{ Retrieves the code stored in the \code{qenv}. diff --git a/man/qenv.Rd b/man/qenv.Rd index 366d24c6..ac9c1a90 100644 --- a/man/qenv.Rd +++ b/man/qenv.Rd @@ -23,7 +23,7 @@ Instantiates a \code{qenv} environment. and \code{\link[=within.qenv]{within.qenv()}} functions. \item It stores metadata about the code used to create the data (see \code{\link[=get_code]{get_code()}}). \item It supports slicing (see \code{\link{subset-qenv}}) -\item Is immutable which means that each code evaluation does not modify the original \code{qenv} +\item It is immutable which means that each code evaluation does not modify the original \code{qenv} environment directly. See the following code: \if{html}{\out{
}}\preformatted{q1 <- qenv() diff --git a/vignettes/qenv.Rmd b/vignettes/qenv.Rmd index 314a88ff..4859e32c 100644 --- a/vignettes/qenv.Rmd +++ b/vignettes/qenv.Rmd @@ -16,7 +16,7 @@ A `qenv` inherits from the `environment` class, behaves like an environment, and - `qenv` is a locked environment, and data modification is only possible through the `eval_code` and `within` functions. - It stores metadata about the code used to create the data (see `get_code`). - It supports slicing by `[`. -- Is immutable which means that each code evaluation does not modify the original `qenv` environment directly. +- It is immutable which means that each code evaluation does not modify the original `qenv` environment directly. ### Initialization From 2d062885541c9dac8cddad2336e0c741b4fa120f Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 19 Dec 2024 15:27:44 +0100 Subject: [PATCH 14/21] fix conflict --- man/eval_code.Rd | 4 ---- 1 file changed, 4 deletions(-) diff --git a/man/eval_code.Rd b/man/eval_code.Rd index c512e34e..203a96af 100644 --- a/man/eval_code.Rd +++ b/man/eval_code.Rd @@ -25,11 +25,7 @@ It is possible to preserve original formatting of the \code{code} by providing a \item{expr}{(\code{expression}) to evaluate. Must be inline code, see \verb{Using language objects...}} \item{...}{named argument value will substitute a symbol in the \code{expr} matched by the name. -<<<<<<< HEAD For practical usage see Examples section below.} -======= -For practical examples see the \href{#ref-usage}{usage} above.} ->>>>>>> origin/338_datanames_in_vignettes } \value{ \code{qenv} environment with \code{code/expr} evaluated or \code{qenv.error} if evaluation fails. From 6cbea730189f67194b40d52636b2740e9ea57938 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Fri, 20 Dec 2024 10:43:23 +0100 Subject: [PATCH 15/21] grey put hidden objects --- DESCRIPTION | 2 +- R/qenv-show.R | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 615c079e..1ba6ca81 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -28,13 +28,13 @@ Depends: R (>= 4.0) Imports: checkmate (>= 2.1.0), + cli (>= 3.4.0), grDevices, lifecycle (>= 0.2.0), rlang (>= 1.1.0), stats, utils Suggests: - cli (>= 3.4.0), knitr (>= 1.42), rmarkdown (>= 2.23), shiny (>= 1.6.0), diff --git a/R/qenv-show.R b/R/qenv-show.R index b2fa7447..6c4718f1 100644 --- a/R/qenv-show.R +++ b/R/qenv-show.R @@ -16,5 +16,26 @@ #' @importFrom methods show #' @export setMethod("show", "qenv", function(object) { - rlang::env_print(object@.xData) + env <- get_env(object) + header <- cli::col_blue(sprintf("", rlang::env_label(env))) + locked <- if (environmentIsLocked(env)) { + " [L]" + } else { + "" + } + parent <- sprintf("", rlang::env_label(rlang::env_parent(env))) + cat(cli::style_bold(paste0(header, locked)), sep = "\n") + cat(parent, "\n") + + shown <- ls(object) + lapply(shown, function(x) { + cat(sprintf("- %s: [%s]\n", x, class(object[[x]])[1])) + }) + + hidden <- setdiff(ls(object, all.names = TRUE), shown) + lapply(hidden, function(x) { + cat(cli::style_blurred(sprintf("- %s: [%s]\n", x, class(object[[x]])[1]))) + }) + + invisible(object) }) From 059165fd5416f3aff7c8e459326bd93bd1824aae Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Fri, 20 Dec 2024 10:47:27 +0100 Subject: [PATCH 16/21] Add `Parent: ` --- R/qenv-show.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/qenv-show.R b/R/qenv-show.R index 6c4718f1..e665cbcf 100644 --- a/R/qenv-show.R +++ b/R/qenv-show.R @@ -23,7 +23,7 @@ setMethod("show", "qenv", function(object) { } else { "" } - parent <- sprintf("", rlang::env_label(rlang::env_parent(env))) + parent <- sprintf("Parent: ", rlang::env_label(rlang::env_parent(env))) cat(cli::style_bold(paste0(header, locked)), sep = "\n") cat(parent, "\n") From b2b428d7922139543ff2b843138603c1a04790dd Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Fri, 20 Dec 2024 10:57:47 +0100 Subject: [PATCH 17/21] cli in verdebcheck and precommit --- .pre-commit-config.yaml | 1 + DESCRIPTION | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4fad42b..bd9da0e0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,6 +16,7 @@ repos: name: Regenerate package documentation additional_dependencies: - checkmate + - cli - grDevices - lifecycle - methods diff --git a/DESCRIPTION b/DESCRIPTION index 1ba6ca81..a0187e7e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -45,7 +45,7 @@ VignetteBuilder: rmarkdown RdMacros: lifecycle -Config/Needs/verdepcheck: mllg/checkmate, r-lib/lifecycle, r-lib/rlang, +Config/Needs/verdepcheck: mllg/checkmate, r-lib/cli, r-lib/lifecycle, r-lib/rlang, r-lib/cli, yihui/knitr, rstudio/rmarkdown, rstudio/shiny, r-lib/testthat, r-lib/withr Config/Needs/website: insightsengineering/nesttemplate From 12360f7944cd14facad593c2f1c16c48e686464d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ka=C5=82=C4=99dkowski?= Date: Fri, 20 Dec 2024 11:14:21 +0100 Subject: [PATCH 18/21] Update R/qenv-show.R MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: André Veríssimo <211358+averissimo@users.noreply.github.com> Signed-off-by: Dawid Kałędkowski --- R/qenv-show.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/qenv-show.R b/R/qenv-show.R index e665cbcf..93bfe222 100644 --- a/R/qenv-show.R +++ b/R/qenv-show.R @@ -27,7 +27,7 @@ setMethod("show", "qenv", function(object) { cat(cli::style_bold(paste0(header, locked)), sep = "\n") cat(parent, "\n") - shown <- ls(object) + shown <- vapply(rlang::syms(ls(object)), deparse, character(1L), backtick = TRUE) lapply(shown, function(x) { cat(sprintf("- %s: [%s]\n", x, class(object[[x]])[1])) }) From d60755cfa419a46ad61e0caeee525f29ef48a906 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Fri, 20 Dec 2024 11:20:19 +0100 Subject: [PATCH 19/21] fix the print --- R/qenv-show.R | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/R/qenv-show.R b/R/qenv-show.R index 93bfe222..9783e0fd 100644 --- a/R/qenv-show.R +++ b/R/qenv-show.R @@ -27,9 +27,15 @@ setMethod("show", "qenv", function(object) { cat(cli::style_bold(paste0(header, locked)), sep = "\n") cat(parent, "\n") - shown <- vapply(rlang::syms(ls(object)), deparse, character(1L), backtick = TRUE) + shown <- ls(object) lapply(shown, function(x) { - cat(sprintf("- %s: [%s]\n", x, class(object[[x]])[1])) + cat( + sprintf( + "- %s: [%s]\n", + deparse(rlang::sym(x), backtick = TRUE), + class(object[[x]])[1] + ) + ) }) hidden <- setdiff(ls(object, all.names = TRUE), shown) From fa139e0ee1f97817977550359f39cd83a0de34e6 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Fri, 20 Dec 2024 11:54:43 +0100 Subject: [PATCH 20/21] - unicode lock - Bindings: --- R/qenv-show.R | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/R/qenv-show.R b/R/qenv-show.R index 9783e0fd..f0be98dc 100644 --- a/R/qenv-show.R +++ b/R/qenv-show.R @@ -18,16 +18,12 @@ setMethod("show", "qenv", function(object) { env <- get_env(object) header <- cli::col_blue(sprintf("", rlang::env_label(env))) - locked <- if (environmentIsLocked(env)) { - " [L]" - } else { - "" - } parent <- sprintf("Parent: ", rlang::env_label(rlang::env_parent(env))) - cat(cli::style_bold(paste0(header, locked)), sep = "\n") + cat(cli::style_bold(header), "\U1F512", "\n") cat(parent, "\n") shown <- ls(object) + if (length(shown > 0L)) cat(cli::style_bold("Bindings:\n")) lapply(shown, function(x) { cat( sprintf( From a44e53c965fa3e5cb9c987613de648502006bbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ka=C5=82=C4=99dkowski?= Date: Fri, 20 Dec 2024 21:23:05 +0100 Subject: [PATCH 21/21] Update R/qenv-show.R MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: André Veríssimo <211358+averissimo@users.noreply.github.com> Signed-off-by: Dawid Kałędkowski --- R/qenv-show.R | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/R/qenv-show.R b/R/qenv-show.R index f0be98dc..e389fd76 100644 --- a/R/qenv-show.R +++ b/R/qenv-show.R @@ -36,7 +36,15 @@ setMethod("show", "qenv", function(object) { hidden <- setdiff(ls(object, all.names = TRUE), shown) lapply(hidden, function(x) { - cat(cli::style_blurred(sprintf("- %s: [%s]\n", x, class(object[[x]])[1]))) + cat( + cli::style_blurred( + sprintf( + "- %s: [%s]\n", + deparse(rlang::sym(x), backtick = TRUE), + class(object[[x]])[1] + ) + ) + ) }) invisible(object)