From a415aed7e6f7d970648caeaf9f8745baf0f63d53 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Tue, 3 Sep 2019 09:13:43 -0500 Subject: [PATCH 1/2] Implement print.reactivevalues --- NAMESPACE | 1 + R/reactives.R | 8 ++++++++ R/utils.R | 4 ++++ tests/testthat/print-reactiveValues.txt | 6 ++++++ tests/testthat/test-reactivity.r | 6 ++++++ 5 files changed, 25 insertions(+) create mode 100644 tests/testthat/print-reactiveValues.txt diff --git a/NAMESPACE b/NAMESPACE index 086c3aca8..d7cc9866a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -26,6 +26,7 @@ S3method(format,reactiveExpr) S3method(format,reactiveVal) S3method(names,reactivevalues) S3method(print,reactive) +S3method(print,reactivevalues) S3method(print,shiny.appobj) S3method(str,reactivevalues) export("conditionStackTrace<-") diff --git a/R/reactives.R b/R/reactives.R index 162769359..736b086d4 100644 --- a/R/reactives.R +++ b/R/reactives.R @@ -590,6 +590,14 @@ checkName <- function(x) { ) } +#' @export +print.reactivevalues <- function(x, ...) { + impl <- .subset2(x, "impl") + cat_line("") + cat_line(" Values: ", paste0(impl$.values$keys(sort = TRUE), collapse = ", ")) + cat_line(" Readonly: ", .subset2(x, "readonly")) +} + #' Checks whether an object is a reactivevalues object #' #' Checks whether its argument is a reactivevalues object. diff --git a/R/utils.R b/R/utils.R index 67690eb8b..a6874b85b 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1800,3 +1800,7 @@ constantTimeEquals <- function(raw1, raw2) { sum(as.integer(xor(raw1, raw2))) == 0 } + +cat_line <- function(...) { + cat(paste(..., "\n", collapse = "")) +} diff --git a/tests/testthat/print-reactiveValues.txt b/tests/testthat/print-reactiveValues.txt new file mode 100644 index 000000000..c5c4c4dfd --- /dev/null +++ b/tests/testthat/print-reactiveValues.txt @@ -0,0 +1,6 @@ +> x <- reactiveValues(x = 1, y = 2, z = 3) +> x + + Values: x, y, z + Readonly: FALSE + diff --git a/tests/testthat/test-reactivity.r b/tests/testthat/test-reactivity.r index 55a34e91a..a1fe47f6f 100644 --- a/tests/testthat/test-reactivity.r +++ b/tests/testthat/test-reactivity.r @@ -122,6 +122,12 @@ test_that("ReactiveValues", { expect_error(values$a <- 1) }) +test_that("reactiveValues() has useful print method", { + verify_output(test_path("print-reactiveValues.txt"), { + x <- reactiveValues(x = 1, y = 2, z = 3) + x + }) +}) # Test for overreactivity. funcB has an indirect dependency on valueA (via # funcA) and also a direct dependency on valueA. When valueA changes, funcB From eb0162dccf19e2df1e718e7a9329b800afcfeef6 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Tue, 3 Sep 2019 09:17:02 -0500 Subject: [PATCH 2/2] Add basic print method for shiny.render.function So at least the user isn't exposed to a bunch on internals --- NAMESPACE | 1 + R/shinywrappers.R | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index d7cc9866a..dd5a4caea 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -28,6 +28,7 @@ S3method(names,reactivevalues) S3method(print,reactive) S3method(print,reactivevalues) S3method(print,shiny.appobj) +S3method(print,shiny.render.function) S3method(str,reactivevalues) export("conditionStackTrace<-") export(..stacktraceoff..) diff --git a/R/shinywrappers.R b/R/shinywrappers.R index e7b2ba3bd..27c11bfd7 100644 --- a/R/shinywrappers.R +++ b/R/shinywrappers.R @@ -52,6 +52,11 @@ markRenderFunction <- function(uiFunc, renderFunc, outputArgs = list()) { hasExecuted = hasExecuted) } +#' @export +print.shiny.render.function <- function(x, ...) { + cat_line("") +} + #' Implement render functions #' #' @param func A function without parameters, that returns user data. If the