捕获用于 S3 调度的参数表达式
Capture argument expression used for S3 dispatch
我在 rlang 和 base 之间发现了意想不到的行为差异。正如这句话所证明的那样,差异显然存在。这是从 0.4.1 开始的,但类似的语言仍在 0.4.2 中,现在指的是 enquo
。
In terms of base functions, enexpr(arg) corresponds to base::substitute(arg) (though that function also features complex substitution semantics)
- 任何人都可以使用
substitute()
具有的 rlang 函数匹配行为吗?
- 对于为什么
enexpr()
不起作用有一个很好的解释吗?我猜是因为它与 S3 方法调度有关。
- 我对如何使用 rlang 执行此操作特别感兴趣,我已经可以仅使用 base 实现我想要的行为。
我的示例是无稽之谈,但它强调的是我无法捕获作为第一个参数传递给通用 S3 函数的表达式(在本例中为单个符号,df
)。
library(rlang)
f <- function(obj) {
enexpr(obj)
}
print(f(print("hello")))
#> print("hello")
# behavior matches expectations
df <- data.frame(a = 1:5, b = letters[1:5])
class(df) <- c("custom", class(df))
`[.custom` <- function(x, i) {
call2(expr(`[`), enexpr(x), i)
}
df[4]
#> list(a = 1:5, b = 1:5)[4]
sloop::s3_dispatch(df[4])
#> => [.custom
#> * [.data.frame
#> [.default
#> * [ (internal)
# It's dispatching as expected, but I don't get
# `df[4]` back as a call.
df <- data.frame(a = 1:5, b = letters[1:5])
class(df) <- c("custom", class(df))
`[.custom` <- function(x, i) {
call2(expr(`[`),substitute(x), i)
}
df[4]
#> df[4]
# substitute works
packageVersion("rlang")
#> [1] '0.4.2'
# Created on 2019-12-05 by the reprex package (v0.3.0)
这是 rlang
的 documented issue,可能会在未来的版本中添加支持。
当前的解决方法是在调度时引入另一个级别的报价:
`[` <- function(x, i) {
ex <- eval_tidy( enquo(x) )
UseMethod('[', ex)
}
`[.custom` <- function(x, i)
call2(expr(`[`), enexpr(x), i)
df[4]
# df[4]
我在 rlang 和 base 之间发现了意想不到的行为差异。正如这句话所证明的那样,差异显然存在。这是从 0.4.1 开始的,但类似的语言仍在 0.4.2 中,现在指的是 enquo
。
In terms of base functions, enexpr(arg) corresponds to base::substitute(arg) (though that function also features complex substitution semantics)
- 任何人都可以使用
substitute()
具有的 rlang 函数匹配行为吗? - 对于为什么
enexpr()
不起作用有一个很好的解释吗?我猜是因为它与 S3 方法调度有关。 - 我对如何使用 rlang 执行此操作特别感兴趣,我已经可以仅使用 base 实现我想要的行为。
我的示例是无稽之谈,但它强调的是我无法捕获作为第一个参数传递给通用 S3 函数的表达式(在本例中为单个符号,df
)。
library(rlang)
f <- function(obj) {
enexpr(obj)
}
print(f(print("hello")))
#> print("hello")
# behavior matches expectations
df <- data.frame(a = 1:5, b = letters[1:5])
class(df) <- c("custom", class(df))
`[.custom` <- function(x, i) {
call2(expr(`[`), enexpr(x), i)
}
df[4]
#> list(a = 1:5, b = 1:5)[4]
sloop::s3_dispatch(df[4])
#> => [.custom
#> * [.data.frame
#> [.default
#> * [ (internal)
# It's dispatching as expected, but I don't get
# `df[4]` back as a call.
df <- data.frame(a = 1:5, b = letters[1:5])
class(df) <- c("custom", class(df))
`[.custom` <- function(x, i) {
call2(expr(`[`),substitute(x), i)
}
df[4]
#> df[4]
# substitute works
packageVersion("rlang")
#> [1] '0.4.2'
# Created on 2019-12-05 by the reprex package (v0.3.0)
这是 rlang
的 documented issue,可能会在未来的版本中添加支持。
当前的解决方法是在调度时引入另一个级别的报价:
`[` <- function(x, i) {
ex <- eval_tidy( enquo(x) )
UseMethod('[', ex)
}
`[.custom` <- function(x, i)
call2(expr(`[`), enexpr(x), i)
df[4]
# df[4]