I would like to understand why the ...
argument matches the extra
argument when nesting f()
within g()
.
Say that f()
is this function:
f <- function(..., extra = NULL) {
. <- list(...)
print(.)
}
The output is, as expected, what is contained in the ...
argument:
f("a", "b", "c", extra = "123")
# [[1]]
# [1] "a"
# [[2]]
# [1] "b"
# [[3]]
# [1] "c"
However, when using it within another function, say g()
:
g <- function(..., extra = NULL) {
f(..., extra)
}
The ...
also captures the extra
argument:
g("a", "b", "c", extra = "123")
# [[1]]
# [1] "a"
# [[2]]
# [1] "b"
# [[3]]
# [1] "c"
# [[4]]
# [1] "123"
My question is twofold: (1) why is this the case and (2) how to correctly handle this?
In f()
you define and set an argument called extra, that is never used, thus it doesnt appear anywhere. The f(..., extra)
in g()
captures all the arguments in g and assigns them to ...
in f()
. The extra in g(..., extra)
has nothing to do with the extra in f(..., extra = NULL)
. They have the same names but live in different environments - the environments of g()
and f()
respectively. To achieve the same behaviour assign the g()
's extra to f()
's extra in the function call:
g1 <- function(..., extra = NULL) {
f(..., extra = extra)
}
> g1("a", "b", "c", extra = NULL)
[[1]]
[1] "a"
[[2]]
[1] "b"
[[3]]
[1] "c"
>