I am trying to wrap my head around a problem I ran into that I think largely revolves around environments, lazy evaluation and issues related to these things. I have a main function (foo1 below) that in my actual use case is quite extensive. For this reason I am trying to provide some wrapper functions (foo2 and foo3) that modify specific elements of the main function.
My problem is that I in the end don't obtain actual values, but I obtain symbols. Can someone provide some guidance as to what I need to with environments and what not to get this sorted?
Here's my MWE:
foo1 <- function(foo, a, b, c=1, d=1) {
if (!missing(foo)) {
mcall <- as.list(match.call())[-(1:2)]
call_names <- names(mcall)
foo <- foo[-which(names(foo) %in% call_names)]
foo <- c(foo, mcall)
} else {
foo <- list(a=a, b=b, c=c, d=d)
}
return(foo)
}
foo2 <- function(a, b) {
foo1(a=a, b=b)
}
foo3 <- function(foo, c, d) {
foo1(foo, c=c, d=d)
}
f <- foo2(a=1, b=1)
f <- foo3(f, c=2, d=2)
str(f)
> str(f)
List of 4
$ a: num 1
$ b: num 1
$ c: symbol c
$ d: symbol d
Here I want c and d to be equal to 2, but they are symbols.
When you use
match.call, it prevents evaulation of the parameters. If you want to evaluate the parameters, then you need to explicitly do so. For exampleThis turns the call to
foo1into a call tolist()and evaluates the result. Another option would be just to usemget()with the variables in the local environment that you want to capture. This will trigger the evaulation