Remove ellipsis from theme#1762
Conversation
R/theme.r
Outdated
| elements <- as.list(environment()) | ||
| elements$complete <- NULL | ||
| elements$validate <- NULL | ||
| elements <- elements[lapply(elements, class) != "name"] |
There was a problem hiding this comment.
I would love some feedback on whether this is the best way to capture all non-missing arguments as evaluated values...?
R/theme.r
Outdated
| #' @param rect all rectangular elements (\code{element_rect}) | ||
| #' @param text all text elements (\code{element_text}) | ||
| #' @param title all title elements: plot, axes, legends (\code{element_text}; | ||
| #' inherits from \code{text}) |
There was a problem hiding this comment.
Can you please indent the second and subsequent lines?
R/theme.r
Outdated
| elements <- c(as.list(environment()), list(...)) | ||
| elements$complete <- NULL | ||
| elements$validate <- NULL | ||
| elements <- elements[lapply(elements, class) != "name"] |
There was a problem hiding this comment.
Why is this necessary? Regardless, it would be cleaner to use vapply() + is.name()
There was a problem hiding this comment.
If we don't remove name elements the theme validation will complain
There was a problem hiding this comment.
But why? Where do those name elements come from?
There was a problem hiding this comment.
these are missing arguments - they exist in the environment and is added to the list as name objects
R/theme.r
Outdated
| plot.caption, plot.margin, strip.background, strip.text, | ||
| strip.text.x, strip.text.y, strip.switch.pad.grid, | ||
| strip.switch.pad.wrap, ..., complete = FALSE, validate = TRUE) { | ||
| elements <- c(as.list(environment()), list(...)) |
There was a problem hiding this comment.
Hmmmm, I don't like this but I don't see a better way except creating the massive named list by hand (which seems likely to be error prone).
There was a problem hiding this comment.
I would really prefer if this was extracted into a separate function and gained a couple of safe guards:
find_args <- function(...) {
env <- parent.frame()
args <- names(formals(sys.function(sys.parent(1))))
vals <- c(as.list(env)[args], list(...))
vals <- vals[!vapply(vals, identical, quote(expr = ), FUN.VALUE = logical(1))]
vals
}
f <- function(a = 1, b = 2, c = 3, d, e, abcdefasdfgasdfasdfasd) {
find_args()
}
f(10, abc = 10)There was a problem hiding this comment.
This is slightly more elegant:
find_args <- function(...) {
env <- parent.frame()
args <- names(formals(sys.function(sys.parent(1))))
vals <- mget(args, envir = env)
vals <- vals[!vapply(vals, identical, quote(expr = ), FUN.VALUE = logical(1))]
c(vals, list(...))
}There was a problem hiding this comment.
is_missing_arg <- function(x) identical(x, quote(expr = )))There was a problem hiding this comment.
And even better:
find_args <- function(...) {
env <- parent.frame()
args <- names(formals(sys.function(sys.parent(1))))
vals <- mget(args, envir = env)
vals <- vals[!vapply(vals, is_missing_arg, logical(1))]
modifyList(vals, list(...))
}|
@wch I have vague memory you thought about this problem (capturing all arguments) a bit |
R/theme.r
Outdated
| elements <- c(as.list(environment()), list(...)) | ||
| elements$complete <- NULL | ||
| elements$validate <- NULL | ||
| elements <- elements[!vapply(elements, is.name, logical(1))] |
There was a problem hiding this comment.
The absolutely correct check is:
elements <- elements[!vapply(elements, identical, quote(expr = ), FUN.VALUE = logical(1))]# Conflicts: # R/theme.r # man/theme.Rd # tests/testthat/test-theme.r
R/utilities.r
Outdated
| # named .ignore | ||
| # @param ... passed on in case enclosing function uses ellipsis in argument list | ||
| # @param .ignore remove these arguments from the list | ||
| find_args <- function(..., .ignore = NULL) { |
There was a problem hiding this comment.
Why not drop .ignore and just use (e.g.) complete = NULL, validate = NULL)?
There was a problem hiding this comment.
Because validate_theme will throw an error if they are included in the list
There was a problem hiding this comment.
find_args(..., complete = NULL, validate = NULL)There was a problem hiding this comment.
Then modifyList will remove them
There was a problem hiding this comment.
Ah - didn't think of that
NEWS.md
Outdated
| * Themes are more homogeneous visually, and match `theme_grey` better. | ||
| (@jiho, #1679) | ||
|
|
||
| * The `theme()` constructor now has named arguments rather than ellipsis. |
There was a problem hiding this comment.
"This should make autocomplete substantially more useful"
Current coverage is 66.18% (diff: 100%)@@ master #1762 diff @@
==========================================
Files 157 157
Lines 5112 5119 +7
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 3381 3388 +7
Misses 1731 1731
Partials 0 0
|
R/utilities.r
Outdated
| # Get all arguments in a function as a list. Will fail if an ellipsis argument | ||
| # named .ignore | ||
| # @param ... passed on in case enclosing function uses ellipsis in argument list | ||
| # @param .ignore remove these arguments from the list |
There was a problem hiding this comment.
This needs to be removed now, other LGTM
|
This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/ |
Fixes #1744