Reputation: 5779
I wrote a function that uses match.call
, and it works when I call the function directly, however, when the function is called within another function it breaks. I believe it has to do with how match.call
handles environments, but I can't figure it out. Here is a reproducable example:
tester <- function() {
var <- "helloworld"
myFunc(var)
}
myFunc <- function(x) {
tmp <- match.call()
tmp[[1]] <- quote(toupper)
eval(tmp)
}
tester() # error
myFunc("helloworld") # works fine
I believe that when myFunc
is called within tester
it can't find var
because it exists in the isolated environment of the tester
function.
Any ideas on how to get myFunc
to work inside tester
would be appreciated. I've tried changing the environment for eval
and match.call
, but to no avail.
Upvotes: 3
Views: 230
Reputation: 545528
Your suspicion is exactly right.
The very simple solution is to evaluate the function in its parent’s context: replace eval
with eval.parent
.
myFunc <- function(x) {
tmp <- match.call()
tmp[[1]] <- quote(toupper)
eval.parent(tmp)
}
Generally, the function traceback
can help tremendously with debugging similar issues:
> tester()
Error in as.character(x) :
cannot coerce type 'closure' to vector of type 'character'
Ok, but which “closure” (= function) are we talking about?
> traceback()
5: toupper(x = var)
4: eval(expr, envir, enclos)
3: eval(tmp) at #5
2: myFunc(var) at #5
1: tester()
The first line has the clue: toupper(x = var)
. In the context of tester
, var
refers to the function (closure) stats::var
which is found because its package is attached.
Upvotes: 5