9

これは、sys.parent() と環境の関係を理解するために私が書いた奇妙な再帰関数です。

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)
}

関数を実行すると、

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!

ここでは多くのことが行われていますが、私の質問は単純にしておきます: なぜ sys.parent() は最初に 1 (0 から 1) ずつ増加し、次に 3 (つまり、1、4、7、10 .. .)?

4

2 に答える 2

9

diveこれは、経由で呼び出すためですeval。以下の例で明確になります。

> 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!

これは変更されたバージョンで、1 ずつインクリメントされます。

> 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!
于 2013-06-19T05:12:09.640 に答える
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!
于 2013-06-19T13:39:33.317 に答える