Я хочу создать функцию check_sym
, которая принимает в качестве аргумента другую функцию f
и проверяет, используется ли внутри f
указанная c функция.
В частности, я хочу проверить, находится ли внутри f
используется нестандартная оценка в виде !! sym
.
Я могу сделать это с помощью простого трюка, который превращает тело функции в строку символов, а затем использует регулярное выражение для проверки "!!sym\\("
,
library(dplyr)
library(purrr)
library(rlang)
check_sym <- function(f) {
f <- as.list(body(f))
f <- unlist(as.character(f))
purrr::some(f, function(x) grepl("!!sym\\(", x))
}
foo <- function(df, x) {
select(df, !! sym(x))
}
check_sym(foo)
#> [1] TRUE
Создано в 2020-02-16 с помощью пакета Представить (v0.3.0)
Однако, хотя это возможно, Я ищу способ, который не основывается на символьных строках и регулярных выражениях, а в идеале на некотором методе, который смотрит внутрь функции и «видит» все вызовы функций на более глубоком уровне, который был бы более надежным.
Любые идеи приветствуются.
Окончательное решение на основе принятого ответа:
На основании приведенного ниже ответа MrFlick мое реальное решение следующее:
Я определяю check_syms as:
check_sym <- function(f) {
grepl("!!sym", paste(all.names(body(f)), collapse = ""))
}
Он правильно определяет функции, которые вызывают функцию на "!! sym"
, по сравнению с функциями, которые вызывают только, например, paste0("!!sym")
.
foo <- function(df, x) {
select(df, !! sym(x))
}
test_f <- function(x) {
print(paste0("!!sym", x))
}
check_sym(foo)
#> [1] TRUE
check_sym(test_f)
#> [1] FALSE