[英]Why does match.call not work when the original call is wrapped in a function?
我想通過 function arguments 在其內部遞歸調用 function (當然,通常具有中斷條件)。
我了解到match.call
應該可以捕獲所有 arguments,並且它可以工作 - 直到我將原始調用包裝在另一個 function 中。
inner <- function(my_arg) {
message(my_arg)
do.call("inner", as.list(match.call()[-1]))
}
# this yields an error ... (unexpected)
outer <- function() {
mydata <- data.frame(1)
inner(mydata)
}
outer()
# ... while this yields an infinite loop (expected)
mydata <- data.frame(1)
inner(mydata)
這輸出:
1
Error in is.data.frame(my_arg) : object 'mydata' not found
這是為什么? 這是故意的嗎? 我怎樣才能解決這個問題?
這個錯誤真的很難解釋,因為它是do.call
、 match.call
和遞歸相互作用的結果。 當嵌套調用inner(my_arg = mydata)
的承諾被強制執行時,就會出現問題。 當message
被調用時,R 搜索 function scope,如果 ZA8CFDE6331BD49EB2AC96F8 未找到封閉環境。 當嵌套調用中的 promise 未被強制(由於您的do.call("inner", as.list(match.call()[-1]))
構造)時,這似乎失敗了。
> traceback()
5: message(my_arg) at #2
4: inner(my_arg = mydata)
3: do.call("inner", as.list(match.call()[-1])) at #4
2: inner(mydata) at #4
1: outer()
我建議你研究一下語言定義,例如 Section 4.3.3 。
另外,為什么你需要match.call
這里? 只需使用inner(my_arg)
而不是do.call
和match.call
構造。 這立即迫使 promise 一切正常。
這是因為范圍界定而發生的。 希望對您的兩個函數的這種修改能夠清楚地了解正在發生的事情(沒有無限循環)。 以及如何解決它。
inner <- function(my_arg)
{
mc <- match.call()
cat("Call to inner:\n")
print(mc)
cat("\nSymbol to be evaluated within \"inner\":\n")
print(as.list(mc)$my_arg)
cat("\nSymbol evaluated in scope of \"inner\":\n")
tryCatch(print(eval(as.list(mc)$my_arg)),
error = function(e) cat("**Error** - symbol not found\n"))
cat("\nSymbol evaluated in parent frame of \"inner\":\n")
tryCatch(print(eval(as.list(mc)$my_arg, envir = parent.frame())),
error = function(e) cat("**Error** - symbol not found\n"))
}
outer <- function()
{
my_data <- "outer test string"
inner(my_data)
}
我們可以測試如下:
inner("inner test string")
#> Call to inner:
#> inner(my_arg = "inner test string")
#>
#> Symbol to be evaluated within "inner":
#> [1] "inner test string"
#>
#> Symbol evaluated in scope of "inner":
#> [1] "inner test string"
#>
#> Symbol evaluated in parent frame of "inner":
#> [1] "inner test string"
outer()
#> Call to inner:
#> inner(my_arg = my_data)
#>
#> Symbol to be evaluated within "inner":
#> my_data
#>
#> Symbol evaluated in scope of "inner":
#> **Error** - symbol not found
#>
#> Symbol evaluated in parent frame of "inner":
#> [1] "outer test string"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.