UPDATE R język określa environment
jako posiadające ramki. Zwykle myślę o klatkach jako klatek stosu, a nie jako odwzorowanie od nazwy do wartości - ale wtedy jest oczywiście data.frame
, który odwzorowuje nazwy kolumn na wektory (a następnie niektóre ...). Myślę, że większość zamieszania wynika z faktu, że oryginalny język S (i wciąż S-Plus) nie miał obiektów środowiskowych, więc wszystkie "ramki" były w zasadzie tym, czym są obiekty środowiskowe, z tym wyjątkiem, że mogły istnieć tylko jako część stosu wywołań.
Na przykład w S-Plus dokument dla sys.nframe
mówi "sys.nframe zwraca indeks numeryczny bieżącej klatki na liście wszystkich klatek." ... to brzmi dla mnie bardzo podobnie do ramek stosu ... Więcej informacji o ramkach stosu można znaleźć tutaj: http://en.wikipedia.org/wiki/Call_stack#Structure
Rozszerzyłem niektóre z poniższych wyjaśnień i konsekwentnie używam terminu "ramka stosu" (mam nadzieję).
END UPDATE
bym je wyjaśnić tak:
Środowisko jest obiektem, który mapuje nazwy zmiennych na wartości. Każde mapowanie nazywa się wiązaniem. Wartość może być wartością rzeczywistą lub obietnicą. Środowisko ma środowisko nadrzędne (z wyjątkiem pustego środowiska). Podczas wyszukiwania symbolu w środowisku, którego nie można znaleźć, przeszukiwane są również środowiska nadrzędne.
Obietnica to nieoceniona ekspresja i środowisko, w którym można oceniać wyrażenie. Kiedy ocena jest oceniona, zostaje zastąpiona wartością generowaną.
Zamknięcie jest funkcją i środowiska, że funkcja została zdefiniowana w funkcji takich jak lm
musiałby środowiska statystyki nazw i zdefiniowany przez użytkownika funkcji do miałby globalne środowisko. - ale funkcję f
zdefiniowane w innej funkcji g
miałoby środowisko lokalne dla g
jako swoje środowisko.
Ramka stosu (lub rekord aktywacji) reprezentuje wpisy na stosie wywołań. Każda klatka stosu ma lokalne środowisko, w którym funkcja jest wykonywana, i wyrażenie funkcji (tak, że działa sys.call
).
Podczas wywołania funkcji tworzone jest środowisko lokalne z ustawionym rodzica na środowisko zamknięcia, argumenty są porównywane z formalnymi argumentami funkcji, a te wiązania są dodawane do środowiska lokalnego (zgodnie z obietnicą). Niezrównanym argumentom formalnym przypisywane są domyślne wartości (obietnice) funkcji (jeśli występują) i oznaczone jako brakujące. W tym środowisku lokalnym i wyrażeniu wywołania tworzona jest ramka stosu. Ramka stosu jest popychana na stos wywołań, a następnie korpus funkcji jest oceniany w tym lokalnym środowisku.
... więc wszystkie symbole w organizmie będzie wyglądał w środowisku lokalnym (formalne argumenty i zmienne lokalne), a jeśli nie znaleziono w środowisku dominującej (co jest środowisko zamknięcie) i rodziców środowisko rodzicielskie i tak dalej, dopóki nie zostanie znalezione.
Należy zwrócić uwagę, że środowisko ramki stosu rodzica to NOT wyszukiwane w tym przypadku. parent.frame
, sys.frame
funkcje dostaje środowisk na stosie połączeń - czyli środowisko rozmówcy i środowisko rozmówcy dzwoniącego itd ...
# 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: To nie skromność; kucyki są niechlujne. Nie czytałem tego. Odbiorę kopię i odpowiem na własne pytanie. –
Czy moja odpowiedź jest zbliżona do tego, czego szukałeś, czy też powinienem wyjaśnić jakąkolwiek jej część? – Tommy