2013-06-19 10 views
8

o to dziwaczna funkcja rekurencyjna Pisałem pomóc mi zrozumieć relacje między sys.parent() i środowiska:zagnieżdżone funkcje sys.parent i środowisk w R

dive = function(level = 1, max.depth = 5) 
{ 
    m = match.call() 
    print(paste("sys.frame() says", format(sys.frame()))) 
    print(paste("sys.parent() says", sys.parent())) 
    print(paste("sys.frame(sys.parent()) says", format(sys.frame(sys.parent())))) 
    m[[2]] = m[[2]]+1 
    if(m[[2]] > max.depth) 
    stop("Not actually an error -- we're just tripping out!") 
    eval(m) 
} 

Uruchamianie funkcji daje

dive(level = 1, max.depth = 5) 

[1] "sys.frame() says <environment: R_GlobalEnv>" 
[1] "sys.parent() says 0" 
[1] "sys.frame(sys.parent()) says <environment: R_GlobalEnv>" 
[1] "sys.frame() says <environment: R_GlobalEnv>" 
[1] "sys.parent() says 1" 
[1] "sys.frame(sys.parent()) says <environment: 0x2831dd0>" 
[1] "sys.frame() says <environment: R_GlobalEnv>" 
[1] "sys.parent() says 4" 
[1] "sys.frame(sys.parent()) says <environment: 0x3b1dff8>" 
[1] "sys.frame() says <environment: R_GlobalEnv>" 
[1] "sys.parent() says 7" 
[1] "sys.frame(sys.parent()) says <environment: 0x3b31c68>" 
[1] "sys.frame() says <environment: R_GlobalEnv>" 
[1] "sys.parent() says 10" 
[1] "sys.frame(sys.parent()) says <environment: 0x3c238c0>" 
Error in dive(level = 5, max.depth = 5) : 
    Not actually an error -- we're just tripping out! 

jest dużo się tu dzieje, ale będę trzymać moje pytanie proste: Dlaczego sys.parent() zwiększamy najpierw przez 1 (od 0 do 1), a następnie kolejno przez 3 (czyli 1 , 4, 7, 10 ...)?

+1

Może się okazać się pomocne: https://github.com/hadley/devtools/wiki/Environments#function-environments – hadley

+0

również tutaj: http://obeautifulcode.com/R/How- R-Wyszukiwania-i-Finds-Stuff / – zkurtz

Odpowiedz

8

To dlatego, że dzwonisz pod numer dive przez eval. Poniższy przykład będzie jasno:

> dive = function(level = 1, max.depth = 5) 
+ { 
+ m = match.call() 
+ print(sys.calls()) 
+ cat("======================\n\n") 
+ m[[2]] = m[[2]]+1 
+ if(m[[2]] > max.depth) 
+  stop("Not actually an error -- we're just tripping out!") 
+ eval(m) 
+ } 
> 
> dive(level = 1, max.depth = 3) 
[[1]] 
dive(level = 1, max.depth = 3) 

====================== 

[[1]] 
dive(level = 1, max.depth = 3) 

[[2]] 
eval(m) 

[[3]] 
eval(expr, envir, enclos) 

[[4]] 
dive(level = 2, max.depth = 3) 

====================== 

[[1]] 
dive(level = 1, max.depth = 3) 

[[2]] 
eval(m) 

[[3]] 
eval(expr, envir, enclos) 

[[4]] 
dive(level = 2, max.depth = 3) 

[[5]] 
eval(m) 

[[6]] 
eval(expr, envir, enclos) 

[[7]] 
dive(level = 3, max.depth = 3) 

====================== 

Error in dive(level = 3, max.depth = 3) : 
    Not actually an error -- we're just tripping out! 

Oto zmodyfikowana wersja, która zwiększa się o jeden.

> dive = function(level = 1, max.depth = 5) 
+ { 
+ print(sys.calls()) 
+ cat("======================\n\n") 
+ if(level+1 > max.depth) 
+  stop("Not actually an error -- we're just tripping out!") 
+ dive(level+1, max.depth) 
+ } 
> 
> dive(level = 1, max.depth = 3) 
[[1]] 
dive(level = 1, max.depth = 3) 

====================== 

[[1]] 
dive(level = 1, max.depth = 3) 

[[2]] 
dive(level + 1, max.depth) 

====================== 

[[1]] 
dive(level = 1, max.depth = 3) 

[[2]] 
dive(level + 1, max.depth) 

[[3]] 
dive(level + 1, max.depth) 

====================== 

Error in dive(level + 1, max.depth) : 
    Not actually an error -- we're just tripping out! 
0
1> dive = function(level = 1, max.depth = 5) 
1+ { 
1+ print(paste("sys.parent() says", sys.parent())) 
1+ if(level+1 > max.depth) 
1+  stop("Not actually an error -- we're just tripping out!") 
1+ dive(level+1, 5) 
1+ } 
1> dive(level = 1, max.depth = 5) 
[1] "sys.parent() says 0" 
[1] "sys.parent() says 1" 
[1] "sys.parent() says 2" 
[1] "sys.parent() says 3" 
[1] "sys.parent() says 4" 
Error in dive(level + 1, 5) : 
    Not actually an error -- we're just tripping out! 
Powiązane problemy