Let's say I have an expression representing a function call, where some arguments are named and some are positional.
expr <- quote(mean(1:5, na.rm = TRUE))
Would it be possible to extract the arguments and all of their names?
magic_function(expr)
#> $x
#> 1:5
#>
#> $na.rm
#> TRUE
Obviously this would be impossible if some of the positional arguments fall into .... However, I'm interested in cases where the names of positional arguments could be extracted from the formals.
The rlang package has call_args() which comes close, but it doesn't give the name of the positional arguments.
rlang::call_args(expr)
#> [[1]]
#> 1:5
#>
#> $na.rm
#> [1] TRUE
I thought of a wrapper around call_args which compares its argument names with those obtained by fn_fmls_names, gets the difference and then sets the missing argument names. This would work but feels a bit messy. Also, it wouldn't work with generics.
For a truer-to-life example demonstrating the issue with generics, let's say my expression is actually
expr <- quote(DBI::dbConnect(RSQLite::SQLite(), ":memory:"))
DBI::dbConnect has two standard arguments: drv for the driver object and ... for any necessary setup arguments. However, the RSQLite method for dbConnect has many more arguments, such as dbname (to which ":memory:" is assigned).
So my hope would be to have some sort of magic_function(expr) which outputs
#> $drv
#> RSQLite:SQLite() # or something...
#> $dbname
#> ":memory:"
So, is it possible to get something similar, but detecting that the positional argument in the mean() example is x = 1:5 more elegantly? And for extra brownie points, this would also have to somehow handle generics like the dbConnect() example!
Given R is lazily evaluated, I wouldn't be surprised if this isn't possible (probably method selection from generics is only done once the generic is actually evaluated, not when it's merely quoted), but I haven't really gotten my head around how this evaluation works under the hood.