Где обрабатываются отсутствующие точки (`...`)?
Если мы рассмотрим тело функции с точками ...
в списке аргументов, мы обычно можем найти функцию, которая получает эти аргументы точек.
Например, мы можем видеть в теле sapply()
, что аргументы точек передаются до lapply()
.
sapply
# function (X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)
# {
# FUN <- match.fun(FUN)
# answer <- lapply(X = X, FUN = FUN, ...)
# ## rest of function body
# }
# <bytecode: 0x000000000e05f0b0>
# environment: namespace:base>
Однако в lapply()
в списке аргументов есть точки ...
, но не в теле функции.
lapply
# function (X, FUN, ...)
# {
# FUN <- match.fun(FUN)
# if (!is.vector(X) || is.object(X))
# X <- as.list(X)
# .Internal(lapply(X, FUN))
# }
# <bytecode: 0x0000000009414f08>
# <environment: namespace:base>
Итак, где обрабатываются точки ...
аргументов в lapply()
? Что/куда они перешли? Мы не можем передать их на match.fun()
. Я предполагаю, что они переданы в .Internal()
, но я не вижу причин для этого работать, когда я не вижу, чтобы они передавались в любую функцию в теле функции.
Ответы
Ответ 1
Они явно не передаются в .Internal
, но я считаю, что они доступны для do_lapply
(в src/main/apply.c) через динамическую область. Правила обзора могут несколько отличаться от обычных, поскольку .Internal
является примитивной функцией.
Вы можете видеть, что ...
(R_DotsSymbol
) добавляется в вызов функции lapply
создает, поэтому они доступны для вызова функции для каждого элемента списка. tmp
примерно эквивалентен X[[i]]
, а R_fcall
примерно эквивалентен FUN(X[[i]], ...)
.
SEXP tmp = PROTECT(LCONS(R_Bracket2Symbol,
LCONS(X, LCONS(isym, R_NilValue))));
SEXP R_fcall = PROTECT(LCONS(FUN,
LCONS(tmp, LCONS(R_DotsSymbol, R_NilValue))));