【发布时间】:2023-03-27 22:40:01
【问题描述】:
我发现 rlang 和 base 之间的行为出现了意想不到的分歧。正如这句话所证明的那样,显然存在差异。这是从 0.4.1 开始的,但类似的语言仍在 0.4.2 中,现在指的是enquo。
就基函数而言,enexpr(arg) 对应于 base::substitute(arg)(尽管该函数还具有复杂的替换语义)
- 任何人都可以使用
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的一位作者评论了similar question's answer:他们更喜欢rlang内部的一致性,而不是完全模仿base。 -
感谢亚历克西斯的评论。这是有道理的,只是在包中找不到记录不一致的地方。