Skip to content

Commit

Permalink
145 create qenvs empty (#156)
Browse files Browse the repository at this point in the history
Closes #145 

I suggest we take this opportunity to also do #150

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pawel Rucki <12943682+pawelru@users.noreply.github.com>
Co-authored-by: go_gonzo <dawid.kaledkowski@gmail.com>
  • Loading branch information
4 people committed Dec 4, 2023
1 parent 588c6a0 commit 9f17086
Show file tree
Hide file tree
Showing 35 changed files with 266 additions and 317 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export(get_var)
export(get_warnings)
export(join)
export(new_qenv)
export(qenv)
exportClasses(qenv)
exportMethods("[[")
exportMethods(concat)
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# teal.code 0.4.1.9012

### Breaking Change

* `qenv` objects should now be created with `qenv()` rather than `new_qenv()`. The new constructor always creates an empty object. `new_qenv` is now deprecated.

### Miscellaneous

* Exported the `qenv` class from the package.
Expand Down
9 changes: 2 additions & 7 deletions R/qenv-concat.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,8 @@
#' @include qenv-errors.R
#' @return `qenv` object.
#' @examples
#' q1 <- new_qenv(
#' code = c(iris1 = "iris1 <- iris", mtcars1 = "mtcars1 <- mtcars"),
#' env = list2env(list(
#' iris1 = iris,
#' mtcars1 = mtcars
#' ))
#' )
#' 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")
Expand Down
51 changes: 38 additions & 13 deletions R/qenv-constructor.R
Original file line number Diff line number Diff line change
@@ -1,24 +1,52 @@
#' Initialize `qenv` object
#'
#' Initialize `qenv` object with `code` and `env`. In order to have `qenv` reproducible
#' one needs to initialize with `env` which can be reproduced by the `code`. Alternatively, one
#' can create an empty `qenv` and evaluate the expressions in this object using `eval_code`.
#' @name new_qenv
#' Create an empty `qenv` object.
#'
#' @param code (`character(1)` or `language`) code to evaluate. Accepts and stores comments also.
#' @param env (`environment`) Environment being a result of the `code` evaluation.
#' `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.
#'
#' `new_qenv()` (deprecated and not recommended)
#' can instantiate a `qenv` object with data in the environment and code registered.
#'
#' @name qenv
#'
#' @examples
#' # create empty qenv
#' qenv()
#'
#' @return `qenv` object.
#'
#' @export
qenv <- function() {
q_env <- new.env(parent = parent.env(.GlobalEnv))
lockEnvironment(q_env, bindings = TRUE)
methods::new("qenv", env = q_env)
}


#' @param code `r badge("deprecated")`
#' (`character(1)` or `language`) code to evaluate. Accepts and stores comments also.
#' @param env `r badge("deprecated")` (`environment`)
#' Environment being a result of the `code` evaluation.
#'
#' @examples
#' # create qenv with data and code (deprecated)
#' new_qenv(env = list2env(list(a = 1)), code = quote(a <- 1))
#' new_qenv(env = list2env(list(a = 1)), code = parse(text = "a <- 1", keep.source = TRUE))
#' new_qenv(env = list2env(list(a = 1)), code = "a <- 1")
#'
#' @return `qenv` object.
#'
#' @rdname qenv
#' @aliases new_qenv,environment,expression-method
#' @aliases new_qenv,environment,character-method
#' @aliases new_qenv,environment,language-method
#' @aliases new_qenv,environment,missing-method
#' @aliases new_qenv,missing,missing-method
#' @export
setGeneric("new_qenv", function(env = new.env(parent = parent.env(.GlobalEnv)), code = character()) standardGeneric("new_qenv")) # nolint
setGeneric("new_qenv", function(env = new.env(parent = parent.env(.GlobalEnv)), code = character()) {
lifecycle::deprecate_warn(when = " 0.4.2", what = "new_qenv()", with = "qenv()", always = TRUE)
standardGeneric("new_qenv")
})

#' @rdname new_qenv
#' @export
setMethod(
"new_qenv",
Expand All @@ -28,7 +56,6 @@ setMethod(
}
)

#' @rdname new_qenv
#' @export
setMethod(
"new_qenv",
Expand All @@ -45,7 +72,6 @@ setMethod(
}
)

#' @rdname new_qenv
#' @export
setMethod(
"new_qenv",
Expand All @@ -55,7 +81,6 @@ setMethod(
}
)

#' @rdname new_qenv
#' @export
setMethod(
"new_qenv",
Expand Down
3 changes: 2 additions & 1 deletion R/qenv-eval_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
#' @param code (`character` or `language`) code to evaluate. Also accepts and stores comments
#'
#' @examples
#' q1 <- new_qenv(env = list2env(list(a = 1)), code = quote(a <- 1))
#' q <- qenv()
#' q1 <- eval_code(q, quote(a <- 1))
#' q2 <- eval_code(q1, quote(library(checkmate)))
#' q3 <- eval_code(q2, quote(assert_number(a)))
#'
Expand Down
3 changes: 2 additions & 1 deletion R/qenv-get_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#' @param ... arguments passed to methods.
#' @return named `character` with the reproducible code.
#' @examples
#' q1 <- new_qenv(env = list2env(list(a = 1)), code = quote(a <- 1))
#' q <- qenv()
#' q1 <- eval_code(q, code = quote(a <- 1))
#' q2 <- eval_code(q1, code = quote(b <- a))
#' q3 <- eval_code(q2, code = quote(d <- 2))
#' get_code(q3)
Expand Down
3 changes: 2 additions & 1 deletion R/qenv-get_var.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#' @name get_var
#' @return The value of required variable (`var`) within `qenv` object.
#' @examples
#' q1 <- new_qenv(env = list2env(list(a = 1)), code = quote(a <- 1))
#' q <- qenv()
#' q1 <- eval_code(q, code = quote(a <- 1))
#' q2 <- eval_code(q1, code = "b <- a")
#' get_var(q2, "b")
#' q2[["b"]]
Expand Down
4 changes: 2 additions & 2 deletions R/qenv-get_warnings.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#' @export
#'
#' @examples
#' data_q <- new_qenv()
#' data_q <- eval_code(new_qenv(), "iris_data <- iris")
#' data_q <- qenv()
#' data_q <- eval_code(data_q, "iris_data <- iris")
#' warning_qenv <- eval_code(
#' data_q,
#' bquote(p <- hist(iris_data[, .("Sepal.Length")], ff = ""))
Expand Down
21 changes: 8 additions & 13 deletions R/qenv-join.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
#' \item Both `qenv` objects contain an object of the same name but are not identical. \cr\cr
#' Example:
#' \preformatted{
#' x <- new_qenv(
#' x <- qenv(
#' code = c(mtcars1 = "mtcars1 <- mtcars"),
#' env = list2env(list(mtcars1 = mtcars))
#' )
#' y <- new_qenv(
#' y <- qenv(
#' code = c(mtcars1 = "mtcars1 <- mtcars['wt']"),
#' env = list2env(list(mtcars1 = mtcars['wt']))
#' )
Expand All @@ -28,7 +28,7 @@
#' Otherwise, `join()` will throw an error message.\cr\cr
#' Example:
#' \preformatted{
#' common_q <- new_qenv(code = "v <- 1", env = list2env(list(v = 1)))
#' common_q <- qenv(code = "v <- 1", env = list2env(list(v = 1)))
#' x <- eval_code(
#' common_q,
#' "x <- v"
Expand All @@ -54,7 +54,7 @@
#' \item The usage of temporary variable in the code expression could cause `join()` to fail. \cr\cr
#' Example:
#' \preformatted{
#' common_q <- new_qenv()
#' common_q <- qenv()
#' x <- eval_code(
#' common_q,
#' "x <- numeric(0)
Expand All @@ -80,7 +80,7 @@
#' in both objects but has different value.\cr
#' To fix this, we can set `i <- NULL` in the code expression for both objects.
#' \preformatted{
#' common_q <- new_qenv()
#' common_q <- qenv()
#' x <- eval_code(
#' common_q,
#' "x <- numeric(0)
Expand Down Expand Up @@ -108,20 +108,15 @@
#' @include qenv-errors.R
#' @return `qenv` object.
#' @examples
#' q1 <- new_qenv(
#' code = c(iris1 = "iris1 <- iris", mtcars1 = "mtcars1 <- mtcars"),
#' env = list2env(list(
#' iris1 = iris,
#' mtcars1 = mtcars
#' ))
#' )
#' 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)
#' get_code(qq)
#'
#' common_q <- new_qenv(list2env(list(x = 1)), quote(x <- 1))
#' 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)
Expand Down
2 changes: 1 addition & 1 deletion R/qenv-replace_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#' @seealso [`qenv-class`], [`eval_code`]
#'
#' @section Examples:
#' `q <- new_qenv()` \cr
#' `q <- qenv()` \cr
#' `q <- eval_code(q, expression(i <- iris, ii <- subset(i, Species == "virginica")))` \cr
#' `get_code(q)` \cr
#' `q <- replace_code(q, expression(i <- iris, ii <- subset(i, Species != "virginica")))` \cr
Expand Down
7 changes: 2 additions & 5 deletions R/qenv-show.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
#' @return nothing
#' @importFrom methods show
#' @examples
#' q1 <- new_qenv(
#' code = "a <- 5
#' b <- data.frame(x = 1:10)",
#' env = list2env(list(a = 5, b = data.frame(x = 1:10)))
#' )
#' q <- qenv()
#' q1 <- eval_code(q, expression(a <- 5, b <- data.frame(x = 1:10)))
#' q1
#' @export
setMethod("show", "qenv", function(object) {
Expand Down
4 changes: 2 additions & 2 deletions R/qenv-within.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#'
#' @examples
#'
#' q <- new_qenv()
#' q <- qenv()
#'
#' # execute code
#' q <- within(q, {
Expand All @@ -40,7 +40,7 @@
#' get_code(q)
#'
#' # inject values into code
#' q <- new_qenv()
#' q <- qenv()
#' q <- within(q, i <- iris)
#' within(q, print(dim(subset(i, Species == "virginica"))))
#' within(q, print(dim(subset(i, Species == species)))) # fails
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Below is the showcase of the example usage

```r
library(teal.code)
my_qenv <- new_qenv(env = list2env(list(x = 5)), code = "x <- 5")
my_qenv <- qenv(env = list2env(list(x = 5)), code = "x <- 5")
my_qenv
#> Parent: <environment: package:teal.code>
#> Bindings:
Expand Down
1 change: 1 addition & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ reference:
- get_warnings
- join
- new_qenv
- qenv
- show,qenv-method
- within.qenv
9 changes: 2 additions & 7 deletions man/concat.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/eval_code.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/get_code.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/get_var.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/get_warnings.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9f17086

Please sign in to comment.