获取调用函数"Once Removed"的参数类



这是一个"语言计算"问题,我的技能充其量也不算多。我正在编写一个函数来检查输入参数的类。以下是功能:

chkArgs <- function() {
# Get args of the function that called this function
# stackoverflow.com/q/17256834/633251
args <- as.list(match.call(definition = sys.function(-1),
call = sys.call(-1)))[-1]
print(data.frame(cls = unlist(lapply(args, class)))) # for debugging only
if (class(eval(args[["x"]])) != "integer")
stop ("Argument 'x' was not an integer or not found")
if (class(eval(args[["y"]])) != "integer")
stop ("Argument 'y' was not an integer or not found")
}

该功能按预期工作,使用以下测试功能:

testFunc <- function(x = 1L, y = 1L){ chkArgs(); x + y }

这些呼叫:

testFunc(1L, 1L)
testFunc(3.0, 1L)
testFunc(x = 8L)

现在,如果我们间接调用chkArgs,或者"一旦删除",如下所示:

testFunc2 <- function(x = 1L, y = 1L){
chkArgs()
testFunc(x, y) # also calls chkArg
}
testFunc2(1L, 1L)

我们得到这个输出:

> testFunc2(1L, 1L)
cls
x integer
y integer
cls
x name
y name
Error in eval(args[["x"]]) : object 'x' not found

如何使chkArgs间接工作?

您可以使用解析父函数n在调用链上的形式参数

fargs <- function(n) { mget(names(formals(sys.function(n))), sys.frame(n), inherits=TRUE); }

所以你的chkArgs可以写成

chkArgs <- function() {
args <- fargs(-2);  # 2 because the helper function fargs is yet another level down
if (class(args$x) != "integer")
stop ("Argument 'x' was not an integer or not found")
if (class(args$y) != "integer")
stop ("Argument 'y' was not an integer or not found")
return(args);
}

这两种情况现在都得到了证实。

最初编写的主要问题似乎是内部检查只将xy视为符号,因为它们在eval的直接环境中就是这样。将mgetinherits一起使用将搜索帧,直到值被解析为止。

最新更新