2015-08-16 10 views
12

Se visualizziamo il corpo di una funzione che ha i punti ... nel suo elenco di argomenti, di solito possiamo trovare la funzione che riceve quegli argomenti punti.Dove vengono elaborati i punti assenti (`...`)?

Ad esempio, è possibile vedere nel corpo di sapply() che gli argomenti punti vengono passati a 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> 

Tuttavia, in lapply(), ci sono punti ... nella lista degli argomenti, ma non nel corpo della funzione.

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> 

Quindi, da dove i puntini ... argomenti a lapply() vengono trattati? Cosa/dove sono passati? Non possiamo passarli a match.fun(). Presumo che siano passati in .Internal() ma non vedo alcun motivo per questo funzioni quando non li vedo passati in nessuna funzione nel corpo della funzione.

risposta

13

Non sono esplicitamente passato-.Internal, ma credo che siano a disposizione do_lapply (in src/main/apply.c) tramite scope dinamico. Le regole di scoping possono essere leggermente diverse dal solito, dal momento che .Internal è una funzione primitiva.

Si può vedere che ... (R_DotsSymbol) viene aggiunto alla chiamata di funzione lapply crea, quindi sono disponibili alla chiamata di funzione su ciascun elemento di elenco. tmp equivale approssimativamente a X[[i]] e R_fcall equivale approssimativamente allo 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)))); 
Problemi correlati