【发布时间】:2023-03-31 08:56:01
【问题描述】:
是否有像函数stop 那样获取调用者姓名的“非内部”方式?
我的想法是我有一个小函数,可以检查输入并在不满足某些条件时停止执行。此函数由其他几个使用相同验证代码的人调用。如果输入无效,调用者的环境将被转储(因此我可以看到传递给函数的参数),并暂停执行。
简化示例:
check <- function(x)
{
if(x<0)
{
print(as.list(parent.frame()))
evalq(stop("invalid input."), parent.frame())
}
}
test <- function(x, y)
{
check(x)
}
我认为在调用者的环境中评估表达式quote(stop("blah")) 会使其显示调用者的姓名。但是,结果如下:
test(-1, 2)
# $x
# [1] -1
#
# $y
# [1] 2
#
# Error in eval(substitute(expr), envir, enclos) : invalid input.
如果我在evalq 中使用parent.frame(n) 和n>1,这不会改变。
所以问题来了,实际上是两个问题: 1. 有没有办法获取创建环境的函数的名称(假设它是这样创建的)? 2. 为什么上面的解决方法失败了?
编辑:我说上面的解决方法失败了,因为我希望错误消息显示为
Error in test(x, y) : invalid input.
好像stop 语句是test 正文的一部分。所以问题2可以重述为:2':为什么stop("invalid input.")的评估没有捕捉到调用者的名字,考虑到它是在调用者的环境中评估的?
【问题讨论】:
-
对一个函数以一种特殊的方式来做这件事有点奇怪。为什么不使用
traceback(),只要生成任何错误,它就会起作用? -
@hadley,我在这篇文章中了解了
traceback和sys.call(s)。所以有效:-)。想法是有许多函数调用check来验证它们的输入。如果check检测到错误,它会转储父环境,因此我可以看到传递给函数的所有输入,然后停止。问题是我无法识别调用check并导致错误的函数。我可以使用options(error=traceback),但这会转储整个堆栈调用,这可能会导致一些混乱。感谢 cmets! -
如果您需要完整参考(函数名、行号、源文件),follow here
标签: r