Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save moodymudskipper/d3619acb1a70dfc88eb6fee432eed666 to your computer and use it in GitHub Desktop.
Save moodymudskipper/d3619acb1a70dfc88eb6fee432eed666 to your computer and use it in GitHub Desktop.
match.args()
``` r
matched.arg <- function(...) {
c(...)[1]
}
match.args <- function() {
formal.args <- formals(sys.function(sysP <- sys.parent()))
formal.args <- Filter(function(x) is.call(x) && identical(x[[1]], as.name("matched.arg")), formal.args)
env <- sys.frame(sysP)
for (arg in names(formal.args)) {
choices <- eval(do.call(substitute, list(formal.args[[arg]], list(matched.arg = quote(c)))), env)
arg <- get(arg, parent.frame())
match.arg(arg, choices)
}
}
fun1 <- function(arg = matched.arg("foo", "bar"), y = 1) {
match.args()
arg
}
fun1()
#> [1] "foo"
fun1("foo")
#> [1] "foo"
fun1("bar")
#> [1] "bar"
fun1("baz")
#> Error in match.arg(arg, choices): 'arg' should be one of "foo", "bar"
fun2 <- function(arg = c("foo", "bar"), y = 1) {
arg <- match.arg(arg)
arg
}
fun2()
#> [1] "foo"
fun2("foo")
#> [1] "foo"
fun2("bar")
#> [1] "bar"
fun2("baz")
#> Error in match.arg(arg): 'arg' should be one of "foo", "bar"
# strangely fun1() is 3 times slower with reprex but same performance in the console, something about the stack maybe
bench::mark(fun1(), fun2(), min_time = 2, max_iterations = 100000)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 fun1() 9.92µs 10.78µs 90760. 13.8KB 52.7
#> 2 fun2() 2.38µs 2.71µs 365258. 0B 54.8
bench::mark(fun1("foo"), fun2("foo"), min_time = 2, max_iterations = 100000)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 fun1("foo") 9.47µs 10.33µs 94932. 0B 56.0
#> 2 fun2("foo") 3.12µs 3.48µs 283473. 0B 62.4
bench::mark(fun1("bar"), fun2("bar"), min_time = 2, max_iterations = 100000)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 fun1("bar") 9.51µs 10.29µs 95722. 0B 56.5
#> 2 fun2("bar") 3.16µs 3.44µs 284578. 0B 62.6
```
<sup>Created on 2022-03-25 by the [reprex package](https://reprex.tidyverse.org) (v2.0.1)</sup>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment