I created a function that returns expression as text except when the input is NULL and wondered why the following two functions using tidyeval and base-NSE behave differently:
f_rlang <- function(x) {
if (is.null(x)) return("")
rlang::expr_text(rlang::enexpr(x))
}
f_base <- function(x) {
if (is.null(x)) return("")
deparse(substitute(x))
}
symbol <- "content"
f_rlang(symbol)
#> [1] "\"content\""
f_base(symbol)
#> [1] "symbol"
Created on 2018-10-02 by the reprex package (v0.2.1)
After some investigation, in tidyeval I found I have to capture x before evaluating it. So, the correct version would be:
f_rlang2 <- function(x) {
x_expr <- rlang::enexpr(x)
if (is.null(x)) return("")
rlang::expr_text(x_expr)
}
symbol <- "content"
f_rlang2(symbol)
#> [1] "symbol"
Created on 2018-10-02 by the reprex package (v0.2.1)
But, is this what is supposed to be? If this is quo(), it may be reasonable that it matters whether the promise (right?) is evaluated or not. But, this is expression, which is separated from the environments and doesn't know when and where to get evaluated.
Since I'm not familiar with tidyeval's concepts, I'm not really sure if I should file a issue for this on rlang's repo. Does anyone know are there any nice explanation for this difference between tidyeval and base-NSE?