-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Remove ellipsis from theme #1762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
elements <- as.list(environment()) | ||
elements$complete <- NULL | ||
elements$validate <- NULL | ||
elements <- elements[lapply(elements, class) != "name"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would love some feedback on whether this is the best way to capture all non-missing arguments as evaluated values...?
#' @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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please indent the second and subsequent lines?
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this necessary? Regardless, it would be cleaner to use vapply()
+ is.name()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't remove name
elements the theme validation will complain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why? Where do those name elements come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are missing arguments - they exist in the environment and is added to the list as name objects
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is_missing_arg <- function(x) identical(x, quote(expr = )))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
# 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not drop .ignore
and just use (e.g.) complete = NULL, validate = NULL)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because validate_theme
will throw an error if they are included in the list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
find_args(..., complete = NULL, validate = NULL)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then modifyList
will remove them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah - didn't think of that
@@ -56,6 +56,8 @@ | |||
* 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"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
|
# 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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