ACTUALIZACIÓN R-lang define un environment
como que tiene un bastidor. Tiendo a pensar en marcos como marcos de pila, no como mapeando de nombre a valor, pero luego está, por supuesto, el data.frame
que asigna nombres de columna a vectores (y luego algunos ...). Creo que la mayor parte de la confusión proviene del hecho de que el lenguaje S original (y aún S-Plus) no tenía objetos de entorno, por lo que todos los "marcos" eran esencialmente lo que son los objetos de entorno ahora, excepto que solo podían existir como parte de la pila de llamadas.
Por ejemplo, en S-Plus el documento para sys.nframe
dice "sys.nframe devuelve el índice numérico del fotograma actual en la lista de todos los fotogramas". ... me suena mucho a montones de montones ... Puede leer más sobre montones de montículos aquí: http://en.wikipedia.org/wiki/Call_stack#Structure
Expandí algunas de las explicaciones a continuación y utilizo el término "marco de pila" consistentemente (espero)
FIN DE ACTUALIZACIÓN
Me explico como esto:
Un entorno es un objeto que asigna nombres de variables a los valores. Cada mapeo se llama un enlace. El valor puede ser un valor real o una promesa. Un entorno tiene un entorno principal (a excepción del entorno vacío). Cuando busca un símbolo en un entorno y no se encuentra, también se buscan los entornos principales.
Una promesa es una expresión no evaluada y un entorno en el que evaluar la expresión. Cuando se evalúa la promesa, se reemplaza con el valor generado.
Un cierre es una función y el medio ambiente que la función se define en una función como lm
tendría el entorno de las estadísticas de espacio de nombres y una función definida por el usuario tendría el entorno global -. Sino una función f
definido dentro de otra función g
tendría el entorno local para g
como su entorno.
Un marco de pila (o registro de activación) es lo que representa las entradas en la pila de llamadas. Cada marco de pila tiene el entorno local en el que se ejecuta la función y la expresión de la llamada de función (de modo que sys.call
funciona).
Cuando se ejecuta una llamada de función, se crea un entorno local con su entorno principal en el entorno de cierre, los argumentos se comparan con los argumentos formales de la función y esos enlaces se agregan al entorno local (como promete). A los argumentos formales no coincidentes se les asignan los valores predeterminados (promesas) de la función (si corresponde) y se marcan como faltantes. A continuación, se crea un marco de pila con este entorno local y la expresión de llamada. El marco de pila se empuja en la pila de llamadas y luego el cuerpo de la función se evalúa en este entorno local.
... así que todos los símbolos en el cuerpo será buscado en el entorno local (argumentos formales y variables locales), y si no se encuentra en el entorno de los padres (que es el ambiente de cierre) y la matriz de entorno principal y así sucesivamente hasta que se encuentre.
Tenga en cuenta que el entorno del marco de la pila padre es NO buscado en este caso. El parent.frame
, sys.frame
funciones obtiene los entornos en la pila de llamadas - es decir, el entorno de la persona que llama y el medio ambiente de la persona que llama de la persona que llama, etc ...
# Here match.fun needs to look in the caller's caller's environment to find what "x" is...
f <- function(FUN) match.fun(FUN)(1:10)
g <- function() { x=sin; y="x"; f(y) }
g() # same as sin(1:10)
# Here we see that the stack frames must also contain the actual call expression
f <- function(...) sys.call()
g <- function(...) f(..., x=42)
g(a=2) # f(..., x = 42)
@DirkEddelbuettel: No es modestia; los ponis son desordenados No he leído eso. Tomaré una copia y responderé mi propia pregunta. –
¿Mi respuesta es similar a la que estaba buscando o debería aclarar alguna parte? – Tommy