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.