Usted está siendo disparado por las sutiles diferencias entre los marcos y entornos (que es aún más sutil ya que los marcos son entornos, o tal vez los entornos son marcos) y la diferencia entre lexical and dynamic scoping. Hay algunos detalles en la página de ayuda para parent.frame
y otros lugares distribuidos en diversos documentos.
Para tratar de simplificar:
Su función getter
tiene su propio environment donde se almacenan las variables locales a esa función (x
en este caso). Como R tiene un alcance léxico, significa que el entorno de las funciones tiene un entorno primario definido por donde se define la función, el entorno global en este caso (si estuviera definido dentro de otra función, entonces el entorno primario sería el entorno para ese función).
Cuando se llama a f1
y llama getter
continuación captador trata de encontrar la variable foo
, primero busca en su propio entorno, no lo encuentra allí, entonces se ve en su entorno matriz que es el env mundial y se encuentra foo
con el valor de 1.
Su pensamiento va en la misma línea del alcance dinámico, que los cuadros se aproximan. Cuando se llama al f1
obtiene su propio entorno (dentro del cual foo
se le asignará el valor 2), entonces llama a la función getter
. El entorno de foo
no es el padre de env getter
's (ámbito léxico), pero el entorno de f1
es el marco principal de getter
desde getter
fue llamado desde f1
, por lo que buscar en el entorno de f1
tiene que decirle a la get
función para buscar en el marco principal en lugar del entorno principal.
El resumen de esto es que el entorno primario es el entorno donde se definió una función (ámbito léxico), el marco principal es el marco/entorno desde el que se llamó a la función (ámbito dinámico simulado).
¡Eso lo hizo, gracias! ¿Por qué funciona parent.frame() pero no sys.parent()? ¿Existe un documento que discuta cómo funcionan todas estas diferentes funciones y las diferencias entre referirse a los entornos por número o por nombre? – hgcrpd
@hgcrpd 'sys.parent' devuelve un número entero, no el marco/entorno. 'parent.frame' usa la información' sys.parent' con 'sys.frame' para obtener el marco (no solo su valor entero). –