Voici un croquis de pourquoi ...()
fonctionne de la manière qu'il le fait. Je vais remplir avec plus de détails et de références plus tard, mais cette touche sur les points clés.
Avant d'effectuer la substitution sur l'un de ses composants, substitute()
première analyse de R instruction.
...()
analyse d'un objet d'appel, alors qu' ...
analyse à un nom d'objet.
...
est un objet spécial, destiné uniquement à être utilisé dans les appels de fonction. En conséquence, le code C qui implémente la substitution prend des mesures spéciales pour manipuler ...
quand il se trouve dans un objet d'appel. De semblables précautions ne sont pas prises lors de l' ...
se produit comme un symbole. (Le code est dans les fonctions do_substitute
, substitute
, et substituteList
(surtout les deux derniers) en R_SRCDIR/src/main/coerce.c
.)
Ainsi, le rôle de l' ()
en ...()
est à cause de la déclaration afin d'être analysée comme un appel (aka la langue) de l'objet, de sorte que la substitution sera de retour le déploiement complet de la valeur des points. Il peut paraître surprenant qu' ...
se substituer, même quand il est à l'extérieur de l' ()
, mais: (a) les appels sont stockées en interne sous forme de liste d'objets et (b) de la C code semble pas faire de distinction entre le premier élément de cette liste, et les suivants.
Juste une note de côté: étude de comportement de l' substitute
) ou les classes d'objets divers, je trouve utile de mettre en place un petit bac à sable, comme ceci:
f <- function(...) browser()
f(a = 4, 77, B = "char")
## Then play around within the browser
class(quote(...)) ## quote() parses without substituting
class(quote(...()))
substitute({...})
substitute(...(..., X, ...))
substitute(2 <- (makes * list(no - sense))(...))