rlang::enexpr()
и base::substitute()
не совсем эквивалентны по своему интерфейсу. enexpr()
ожидает одно имя переменной, которое ссылается на один из входных аргументов функции, тогда как substitute()
может работать с произвольными выражениями. Для этого требуется дополнительное арифметическое выражение c - с помощью rlang::expr()
и оператора unquote !!
- для помещения результата enexpr()
в более сложное выражение:
g <- function(x) substitute(x+5)
h <- function(x) rlang::enexpr(x+5)
h2 <- function(x) rlang::expr( !!rlang::enexpr(x) + 5 )
g(a) # a + 5
h(a) # Error: `arg` must be a symbol
h2(a) # a + 5
. f2
работа, вам нужно применить rlang::enexpr()
к каждому аргументу отдельно, затем использовать выражение arithmeti c для составления общего выражения x::y
:
f2 <- function(x,y){
ee <- rlang::expr( `::`(!!rlang::enexpr(x), !!rlang::enexpr(y)) )
do.call('methods',list(ee))
}
f2(broom,tidy)
Обратите внимание, что мы должны использовать ::
в префиксной записи, потому что наличие !!
и ::
рядом друг с другом является проблемой для синтаксического анализатора. Другими словами, выражения типа !!a :: !!b
приводят к ошибкам синтаксического анализа.
Альтернатива состоит в том, чтобы позволить пользователю составить выражение самостоятельно. Таким образом, вы можете выбрать один rlang::enexpr()
:
f3 <- function(x)
do.call('methods',list(rlang::enexpr(x)))
f3( broom::tidy )
Side Note:
Несмотря на то, что expr()
вызывает enexpr()
, этот вызов по отношению к сфере действия expr()
. Рассмотрим,
f1 <- function(x) rlang::enexpr(x)
f2 <- function(x) {
g <- function(y) rlang::enexpr(y)
g(x)
}
Два не эквивалентны, потому что второй enexpr()
ограничен внутренней функцией g()
, а не внешней f2()
.
f1(abc) # abc
f2(abc) # x