【发布时间】:2020-12-03 11:15:31
【问题描述】:
是否可以检索函数调用的函数组件?也就是说,是否可以在另一个函数调用中使用as.list(match.call())。
背景是,我想要一个函数,它接受函数调用并返回所述函数调用的组件。
get_formals <- function(x) {
# something here, which would behave as if x would be a function that returns
# as.list(match.call())
}
get_formals(mean(1:10))
# expected to get:
# [[1]]
# mean
#
# $x
# 1:10
预期结果是 get_formals 返回,因为在提供的函数调用中调用了 match.call()。
mean2 <- function(...) {
as.list(match.call())
}
mean2(x = 1:10)
# [[1]]
# mean2
#
# $x
# 1:10
另一个例子
这个问题背后的动机是检查memoised 函数是否已经包含缓存值。 memoise 有函数has_cache() 但需要以特定方式调用has_cache(foo)(vals),例如,
library(memoise)
foo <- function(x) mean(x)
foo_cached <- memoise(foo)
foo_cached(1:10) # not yet cached
foo_cached(1:10) # cached
has_cache(foo_cached)(1:10) # TRUE
has_cache(foo_cached)(1:3) # FALSE
我的目标是记录函数调用是否被缓存。
cache_wrapper <- function(f_call) {
is_cached <- has_cache()() # INSERT SOLUTION HERE
# I need to deconstruct the function call to pass it to has_cache
# basically
# has_cache(substitute(expr)[[1L]])(substitute(expr)[[2L]])
# but names etc do not get passed correctly
if (is_cached) print("Using Cache") else print("New Evaluation of f_call")
f_call
}
cache_wrapper(foo_cached(1:10))
#> [1] "Using Cache" # From the log-functionality
#> 5.5 # The result from the function-call
【问题讨论】:
-
我假设
get_formals = function (expr) substitute(expr)[[2L]]不足以满足您的目的? -
你要处理多少层环境?我不确定您是想要 Konrad 的方法还是需要更古怪的方法。您的“函数调用”来自哪里,例如一些
deparse操作?如果您可以发布一个演示,说明您将如何使用此检索工具,那将很有帮助。 -
@KonradRudolph 的解决方案差不多了,但我放弃了参数的名称。
-
我只处理一层。我将在上面的代码中添加另一个示例。
标签: r metaprogramming